SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存
1. 使用Redis
在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖。
pom.xml文件如下
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
由于在SpringBoot中默认提供了一套配置,所以在使用本地的redis时,可以不用配置任何文件,只需要引入依赖,然后就可以使用了,
使用Redis中的template类demo如下;
package com.wangx.boot.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; //必须要加Componet使得该组件可以被spring管理起来 @Component public class RedisDAO { @Autowired private StringRedisTemplate redisTemplate; public void set(String key, String value) { ValueOperations operations = redisTemplate.opsForValue(); if (!redisTemplate.hasKey(key)) { operations.set(key,value); System.out.println("添加成功!!!"); } else { System.out.println(operations.get(key)); } } public String get (String key) { return redisTemplate.opsForValue().get(key); } public void del (String key) { redisTemplate.delete(key); } }
测试三个方法,可以成功保存数据到redis中。不得不再感叹一句,SpringBoot开发真的太便利了,当然,如果redis服务器不是在本地机器上,那么,就需要配置一下你得主机和端口。SpringBoot提供了如下配置来支持Redis的使用。
spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster. spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from. spring.redis.database=0 # Database index used by the connection factory. spring.redis.url= # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:password@example.com:6379 spring.redis.host=localhost # Redis server host. spring.redis.jedis.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit. spring.redis.jedis.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections. spring.redis.jedis.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely. spring.redis.jedis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive. spring.redis.lettuce.pool.max-active=8 # Maximum number of connections that can be allocated by the pool at a given time. Use a negative value for no limit. spring.redis.lettuce.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections. spring.redis.lettuce.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely. spring.redis.lettuce.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive. spring.redis.lettuce.shutdown-timeout=100ms # Shutdown timeout. spring.redis.password= # Login password of the redis server. spring.redis.port=6379 # Redis server port. spring.redis.sentinel.master= # Name of the Redis server. spring.redis.sentinel.nodes= # Comma-separated list of "host:port" pairs. spring.redis.ssl=false # Whether to enable SSL support. spring.redis.timeout= # Connection timeout. # TRANSACTION (TransactionProperties) spring.transaction.default-timeout= # Default transaction timeout. If a duration suffix is not specified, seconds will be used. spring.transaction.rollback-on-commit-failure= # Whether to roll back on commit failures.
通过这些配置可以在自己不同的场景下使用redis.
2. 使用mongodb
同样的Mongodb也提供了一套默认的配置,所以我们只需要保证本机中有mongodb服务器,并启动。引入依赖,就可以直接编写我们的mongodb的持久层。
pom.xml文件:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
使用mongodb的代码如下:
package com.wangx.boot.mongo; import com.wangx.boot.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Component; import java.util.List; //必须要加Componet使得该组件可以被spring管理起来 @Component public class MongoDAO { @Autowired private MongoTemplate mongoTemplate; public void insert(User user) { mongoTemplate.insert(user); System.out.println("添加成功"); } public void update(User user) { Criteria criteria = Criteria.where("id").in(user.getId()); Query query = new Query(criteria); Update update = new Update(); update.set("name", user.getName()); update.set("age", user.getAge()); mongoTemplate.updateMulti(query, update, User.class); System.out.println("更新成功!!!"); } public List<User> select (Integer id) { Criteria criteria = Criteria.where("id").in(id); Query query = new Query(criteria); return mongoTemplate.find(query,User.class); } public void delById (Integer id) { Criteria criteria = Criteria.where("id").in(id); Query query = new Query(criteria); mongoTemplate.remove(query, User.class); System.out.println("删除成功!!!"); } public List<User> findAll () { return mongoTemplate.findAll(User.class); } }
示例中提供了增删改查四个方法,测试,数据能成功保存到mongodb数据库中。可以说。在SpringBoot下,大部分的工具中间件的使用方式都是比较简单的。
3. Ehcache缓存的使用
使用缓存需要引入依赖
pom.xml文件
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
配置文件中配置ehcache的配置文件位置,如下:
# 指定当前cache类型,当有多种缓存在同一个系统时可以使用
spring.cache.type=
spring.cache.ehcache.config=classpath:/conf/encache.xml
还需要再启动类上添加注解@EnableCaching表示开启注解。
encache.xml
<ehcache> <cache name="wangCache" eternal="false" maxEntriesLocalHeap="0" timeToIdleSeconds="200"></cache> <!-- eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false --> <!-- maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制 --> <!-- timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态 --> </ehcache>
下面写一个带缓存的持久层代码
package com.wangx.boot.cache.impl; import com.wangx.boot.cache.CachingBook; import com.wangx.boot.dao.impl.BookDAO; import com.wangx.boot.entity.Book; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; /** * * cacheNames 值必须与encache.xml中的某个cache的name一致 */ @CacheConfig(cacheNames = "wangCache") @Repository public class CacheingBookImpl implements CachingBook { @Autowired private BookDAO bookDAO; //value 值必须与encache.xml中的某个cache的name一致 @Cacheable(value = "wangCache") @Override public Book findById(String name) { System.out.println("缓存中没有数据"); return bookDAO.findByName(name); } //value 值必须与encache.xml中的某个cache的name一致 @CachePut("wangCache") @Override public Book updateById(Book book) { System.out.println("更新功能:更新缓存。直接写库: id=" + book); return bookDAO.save(book); } //value 值必须与encache.xml中的某个cache的name一致 @CacheEvict("wangCache") @Override public String deleteById(String id) { System.out.println("删除缓存,直接写库 id=" + id); return "OK"; } }
测试代码:
package com.wangx.boot.controller; import com.wangx.boot.cache.CachingBook; import com.wangx.boot.entity.Book; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api") public class ApiController { @Autowired private CachingBook cachingBook; @RequestMapping(value = "/select", method = RequestMethod.GET) public Book get(@RequestParam(defaultValue = "遮天") String name) { Book book = cachingBook.findById(name); return book; } @RequestMapping(value = "/update", method = RequestMethod.GET) public Book update(@RequestParam(defaultValue = "遮天") String name) { Book bean = cachingBook.findById(name); bean.setAuthor("耳根"); cachingBook.updateById(bean); return bean; } @RequestMapping(value = "/del", method = RequestMethod.GET) public String del(@RequestParam(defaultValue = "遮天") String name) { return cachingBook.deleteById(name); } }
当调用查询时,会先去缓存中获取数据,如果没有,才会调用CacheingBookImpl 中的find方法,并将查询出来的值保存到缓存中,下一次再请求时由于缓存中有数据,所以不会再调用持久层的方法,修改方法每次都会调用持久层方法并修改缓存。delete会删除缓存。cache的几个注解的含义
@CacheConfig 缓存配置
@Cacheable 应用到读取数据的方法上,即可缓存方法,:如查找方法。先从缓存中读取,如果没有再调用方法获取数据,然后把数据存储到缓存中,适用于查找。
@CachePut: 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。和@Cacheable不同的是,它每次都会触发真实的方法调用,适用于更新和插入。
@CacheEvict:主要根据方法配置,能够根据一定的条件对缓存进行清空,适用于删除。
4. 使用Redis缓存
有了前面使用缓存的示例之后,redis操作就非常简单了,只需要引入redis依赖,将配置文件中的spring.cache.type配置为redis,
spring.cache.type=redis.需要注意的是,需要缓存的实体类必须实现序列化,否则会报未序列化的错误。如Book.java
package com.wangx.boot.entity; import javax.persistence.Entity; import javax.persistence.Id; import java.io.Serializable; @Entity public class Book implements Serializable { @Id private int id; private String name; private String author; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Book{" + "id=" + id + ", name='" + name + '\'' + ", author='" + author + '\'' + '}'; } }
其他的代码都不用改,只是将encache换成redis就可以了,测试也跟使用Ehcache作用相同。
使用redis还可以使用配置类自定义一些不同的信息,自定义方式如下:
package com.roncoo.example.util.configuration; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.core.RedisTemplate; /** * redis 自定义缓存管理器 * * @author wujing */ @Configuration public class RedisCacheConfiguration extends CachingConfigurerSupport { /** * 自定义缓存管理器. * * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); // 设置默认的过期时间 cacheManager.setDefaultExpiration(20); Map<String, Long> expires = new HashMap<String, Long>(); // 单独设置 expires.put("roncooCache", 200L); cacheManager.setExpires(expires); return cacheManager; } /** * 自定义key. 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } return sb.toString(); } }; } }
可以根据自己的业务配置不同的信息。