SpringBoot 集成 Redis +SpringCache 做缓存
GitHub 源码: https://github.com/xivinChen/SpringBoot
一. 给 user 加缓存
1. 首先创建 springboot-Redis-cache 模块, 并把 springboot-restful-API 的内容复制过来.
2. 修改三层架构, 即加 service 层
添加 service.UserService 接口, 再创建实现类 service.impl.UserServiceimpl, 记得实现类要加上 @Service 注解. 并实现 user 的增删改查功能. 同时将 Controller 的调用改成 UserService.
3. 加入 Redis cache pool 等依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
4. 配置 Redis
- server:
- port: 8090
- # 扫描 mapper.xml 文件
- mybatis:
- mapper-locations:
- - classpath:mapping/*.xml
- spring:
- application:
- name: springboot-ssm
- datasource:
- type: com.alibaba.druid.pool.DruidDataSource
- driver-class-name: com.MySQL.cj.jdbc.Driver
- url: jdbc:MySQL://127.0.0.1:3306/springboot?serverTimezone=GMT+8&useUnicode=true&characterEncoding=utf-8&useSSL=false
- username: root
- password: 123zxc
- Redis:
- host: 127.0.0.1
- port: 6379
- password: 123zxc
- database: 0
- lettuce:
- pool:
- max-active: 32
- max-wait: 300ms
- max-idle: 16
- min-idle: 8
5. 启动类加上 @EnableCaching 注解
6.Service 加缓存
- @Service
- public class UserServiceImpl implements UserService {
- private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
- @Resource
- private UserMapper userMapper;
- @Override
- @Cacheable(value = "user:id",key = "#id")
- public User getOneUser(int id) {
- logger.info("get one go mysql ...");
- return userMapper.selectByPrimaryKey(id);
- }
- @Cacheable(value = "user:list")
- @Override
- public List<User> findAll() {
- logger.info("find all go mysql ...");
- return userMapper.list();
- }
- @CacheEvict(value = "user:list",allEntries = true)
- @Override
- public int add(User user) {
- return userMapper.insert(user);
- }
- @Caching(
- evict = {
- @CacheEvict(value = "user:id", key = "#user.id"),
- @CacheEvict(value = "user:list", allEntries = true)
- }
- )
- @Override
- public int update(User user) {
- return userMapper.updateByPrimaryKey(user);
- }
- @Caching(
- evict = {
- @CacheEvict(value = "user:id", key = "#id"),
- @CacheEvict(value = "user:list", allEntries = true)
- }
- )
- @Override
- public int delete(int id) {
- return delete(id);
- }
- }
以上 SpringBoot 默认对 Redis 的配置, 如果我们想修改 Redis 的配置, 如序列化方式, 默认过期时间等等. 则需要我们创建 RedisConfig.java 配置类.
二. 手动配置 RedisConfig.java
具体配置如下, 其中一个是操作 Redis 的 RedisTemplate, 一个是缓存使用的 CacheManager, 其中修改了序列化方式, 所以要把原来的缓存清空.
- @Component
- @Configuration
- @ConfigurationProperties("spring.cache.redis")
- public class RedisConfig extends CachingConfigurerSupport {
- private Duration timeToLive = Duration.ofMinutes(30);
- public void setTimeToLive(Duration timeToLive) {
- this.timeToLive = timeToLive;
- }
- @Bean
- public CacheManager cacheManager(RedisConnectionFactory factory) {
- RedisSerializer<String> redisSerializer = new StringRedisSerializer();
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- // 解决查询缓存转换异常的问题
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- // 配置序列化 (解决乱码的问题)
- RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
- .entryTtl(timeToLive)
- .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
- .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
- .disableCachingNullValues();
- RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
- .cacheDefaults(config)
- .build();
- return cacheManager;
- }
- //RedisTemplate 配置
- @Bean
- @SuppressWarnings("all")
- public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
- RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
- template.setConnectionFactory(factory);
- // 配置事务
- template.setEnableTransactionSupport(true);
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
- // key 采用 String 的序列化方式
- template.setKeySerializer(stringRedisSerializer);
- // hash 的 key 也采用 String 的序列化方式
- template.setHashKeySerializer(stringRedisSerializer);
- // value 序列化方式采用 jackson
- template.setValueSerializer(jackson2JsonRedisSerializer);
- // hash 的 value 序列化方式采用 jackson
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
- template.afterPropertiesSet();
- return template;
- }
- }
二. SpringBoot 如何操作 Redis
Springboot 操作 Redis 引入的依赖可以不用引入
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
1. 说明
SpringBoot Redis 提供一个强大的模版操作 Redis, 它就是 RedisTemplate, 使用它可以很方便的操作 Redis 的五大数据类型. 下面我们写一个测试类使用 RedisTemplate 的相关 API.
首先把引入 spring-boot-starter-test 依赖, 同时去掉 junit 依赖, 否则会报错!
2. 添加 RedisTemplateTest
在 test/java/xyz.java1024 下创建 RedisTemplateTest 测试类, 加上 @RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisApp.class) 注解, 指定启动类作用是读取配置信息. 具体代码如下:
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = RedisApp.class)
- public class RedisTemplateTest {
- @Resource
- private RedisTemplate redisTemplate;
- /**
- *
- * 介绍 如何使用 redisTemplate 操作 String List Set ZSet Hash 五种数据类型
- * 本测试只 使用了部分常用的 API, 如在集合等复杂数据类型 有更多的 API 实现更加强大的功能, 查阅相关文档即可!
- *
- */
- /**
- * String 类型 set
- */
- @Test
- public void testSet() {
- redisTemplate.opsForValue().set("test","this is test");
- }
- /**
- * String 类型 get
- */
- @Test
- public void testGet() {
- Object test = redisTemplate.opsForValue().get("test");
- System.out.println("test =" + test);
- }
- /**
- * 添加元素
- */
- @Test
- public void testLSet() {
- redisTemplate.opsForList().leftPush("testList","testList1");
- }
- /**
- * 获取 List 的所有元素
- */
- @Test
- public void testLGet() {
- List testList = redisTemplate.opsForList().range("testList", 0, -1);
- System.out.println("testList =" + testList);
- }
- /**
- * Set 类型 set
- */
- @Test
- public void testSSet() {
- redisTemplate.opsForSet().add("testSet","testSet1");
- }
- /**
- * Set 类型 get
- */
- @Test
- public void testSGet() {
- Set testSet = redisTemplate.opsForSet().members("testSet");
- System.out.println("testSet =" + testSet);
- }
- /**
- * hash set
- */
- @Test
- public void testHSet() {
- redisTemplate.opsForHash().put("testHash","value1","key1");
- redisTemplate.opsForHash().put("testHash","value2","key2");
- }
- /**
- * hash get
- */
- @Test
- public void testHget() {
- Object o = redisTemplate.opsForHash().get("testHash", "value1");
- System.out.println("o =" + o);
- }
- /**
- * Zset set
- */
- @Test
- public void testZSet() {
- redisTemplate.opsForZSet().add("java1024","SpringBoot",10);
- redisTemplate.opsForZSet().add("java1024","SpringCloud",3);
- }
- /**
- * Zset get
- */
- @Test
- public void testZGet() {
- // 正序
- Set all = redisTemplate.opsForZSet().range("java1024", 0, -1);
- System.out.println("all =" + all);
- // 反序
- Set reverseRange = redisTemplate.opsForZSet().reverseRange("java1024", 0, -1);
- System.out.println("reverseRange =" + reverseRange);
- }
- }
总结
操作 Redis 不依赖 SpringCache, 实现 SpringCache 也不止 Redis, 也可以用 ehCache 做缓存! 只是现在主流还是用 Redis 做缓存.
来源: http://www.bubuko.com/infodetail-3373669.html