Springboot2.x 使用 Redis
参考
- https://blog.csdn.net/weixin_43749805/article/details/131399516
- https://juejin.cn/post/7076244567569203208
- https://blog.csdn.net/oJingZhiYuan12/article/details/126386904
注意
- 
class java.lang.Integer cannot be cast to class com.xiaqiuchu.demo.entity.Student (java.lang.Integer is in module java.base of loader 'bootstrap'; com.xiaqiuchu.demo.entity.Student is in unnamed module of loader 'app')
 注解缓存时缓存的方法缓存值,update 返回的是数字类型,导致缓存查询的时候报错转换失败。
- 
entity 类需要 implements java.io.Serializable ,否则可能会导致缓存储存时序列化失败或错误。 
环境
| 环境 | 版本 | 操作 | 
|---|---|---|
| windows | 10 | |
| vs code | 1.84.2 | |
| Spring Boot Extension Pack | v0.2.1 | vscode插件 | 
| Extension Pack for Java | v0.25.15 | vscode插件 | 
| JDK | 11 | |
| Springboot | 2.3.12.RELEASE | |
| mybatis-spring-boot-starter | 2.1.4 | mvn依赖 | 
| spring-boot-starter-cache | mvn依赖 | |
| Apache Maven | 3.8.6 | |
| Redis | 3.0.504 | windows 版本,已停更,建议 linux 中使用 | 
步骤
配置
- 添加 pom.xml依赖。
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 在配置文件中 application.properties增加配置。
不仅仅这些配置,还有其他配置以及连接池的配置
# redis配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
# 连接池配置,连接池配置还需要添加其他依赖。 https://juejin.cn/post/7076244567569203208
- 在 src\main\java\com\xiaqiuchu\demo\config增加RedisConfig.java。
package com.xiaqiuchu.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
  @Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    // key 序列化类
    template.setKeySerializer(new StringRedisSerializer());
    // value 序列化类
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    return template;
  }
}
- 入口文件添加 @EnableCaching注解。
package com.xiaqiuchu.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
使用
- 代码操作。
package com.xiaqiuchu.demo.service;
import java.time.Duration;
import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.mapper.StudentMapper;
@Service
public class StudentService {
    @Resource
    StudentMapper studentMaper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 手动管理缓存
     * @param id
     * @return
     */
    public Student findByIdFromCache(Integer id){
        String cacheKey = "StudentService" + id;
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        if(redisTemplate.hasKey(cacheKey) == null || redisTemplate.getExpire(cacheKey) < 1){
            System.out.println("==查询数据库==");
            valueOperations.set(cacheKey, studentMaper.findById(id), Duration.ofHours(2));
        }
        return (Student) valueOperations.get(cacheKey);
    }
}
- 注解方式
注意:注解方式是缓存的方法返回值,但是像 mybatis 中 update 操作默认返回的是更新条数,如果直接返回更新条数就会导致缓存储存为数字类型,在查询的时候报错
class java.lang.Integer cannot be cast to class com.xiaqiuchu.demo.entity.Student (java.lang.Integer is in module java.base of loader 'bootstrap'; com.xiaqiuchu.demo.entity.Student is in unnamed module of loader 'app')
注解方式获取 key 可以通过
.方式获取对象的属性。
package com.xiaqiuchu.demo.service;
import javax.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import com.xiaqiuchu.demo.entity.Student;
import com.xiaqiuchu.demo.mapper.StudentMapper;
@Service
public class StudentService {
    @Resource
    StudentMapper studentMaper;
    // 该注解用于标记方法的返回结果可以被缓存。当下次调用相同的方法时,如果缓存中存在相同的参数,则直接从缓存中获取结果,而不执行方法体内的代码。如果缓存中不存在相同的参数,则执行方法体内的代码,并将结果存入缓存中。
    @Cacheable(value = "StudentService", key = "#id")
    public Student findById(Integer id){
        System.out.println("==查询==");
        return studentMaper.findById(id);
    }
    public Integer insert(Student student){
        return studentMaper.insert(student);
    }
    // 该注解用于标记方法的返回结果需要放入缓存。无论缓存中是否已存在相同的参数,每次调用该方法都会执行方法体内的代码,并将结果存入缓存中。
    // 方法返回类型要一致,不然储存的就是 Integer。。。 
    @CachePut(value = "StudentService", key = "#student.id")
    public Student updateById(Student student){
        Integer updateNum = studentMaper.updateById(student);
        Assert.isTrue(updateNum > 0, "更新失败");
        return student;
    }
    // 该注解用于标记方法执行后需要清除特定的缓存项。可以指定要清除的缓存项的key,或者通过allEntries参数设置为true来清除所有缓存项。
    @CacheEvict(value = "StudentService", key = "#id")
    public Integer deleteById(Integer id){
        System.out.println("==删除==");
        return studentMaper.deleteById(id);
    }
    
}
    博  主 :夏秋初
地 址 :https://www.cnblogs.com/xiaqiuchu/p/17913496.html
 
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
    
地 址 :https://www.cnblogs.com/xiaqiuchu/p/17913496.html
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号