SpringBoot下使用redis缓存机制
-
案例的目的是:
在用户第一次访问时进行mysql查询,然后将该条数据缓存到redis中,后续的查询都直接在redis中进行缓存查询,
并且在进行修改操作后及时将redis中的数据进行更新 -
用到的工具:
navicat 、RedisDesktopManager、Idea 、Postman
1.导入依赖
<!--redis缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--redis启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!--myBatisPlus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2.配置数据库
application.properties
# mysql配置
spring.datasource.url=jdbc:mysql:///temporary?characterEncoding=utf-8&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=12345
#redis配置
spring.redis.host=172.16.2.134
spring.redis.port=6379
spring.redis.password=123456
spring.redis.database=1
#日志配置
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3.数据库准备
使用navicat连接mySql
使用RedisDesktopManager连接redis
4.实体类 mapper接口 service controller生成
Student
@Data
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private String sSex;
}
StudentMapper
public interface StudentMapper extends BaseMapper<Student> {
}
StudentService
public interface StudentService extends IService<Student> {
Student getById(Integer id);
Student update(Student student);
}
StudentServiceImpl
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
@Cacheable(value = "Student",key = "args[0]")
@Override
public Student getById(Integer id) {
return baseMapper.selectById(id);
}
@CachePut(value = "Student",key = "args[0].id")
@Override
public Student update(Student student) {
baseMapper.updateById(student);
return student;
}
}
StudentController
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/demo3/{a}")
public Student m3(@PathVariable("a") Integer a){
return studentService.getById(a);
}
@PostMapping("/demo4")
public Student m4(@RequestBody Student student){
System.out.println(student);
return studentService.update(student);
}
}
5.运行程序后的结果
-
进行查询
向数据库发送了请求
-
第二次进行访问
语句没有变化
-
redis中存储状况:
可以看到redis中自动存放了数据,但是value值是序列化后的数据,不利于解读,文章最后再说解决方案
-
进行修改
使用postman发送post请求
发送了更新的语句
redis中变化:
可以看到最后的几个字符是不一致的
浏览器中访问:
信息已经发生变化
6. redis中的序列化解决
定义一个配置类,加上@Configuration注入到容器中即可
@Configuration
public class MyRedisConfig {
@Bean
public RedisCacheConfiguration cacheConfiguration(){
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
registerDefaultConverters(conversionService);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()))
.withConversionService(conversionService)
.entryTtl(Duration.ZERO)
.computePrefixWith(CacheKeyPrefix.simple());
return configuration;
}
}
重启后显示结果:
7.缓存注解总结
- 项目开启缓存,在主配置类上加
@EnableCaching
@Cacheable
是表明该方法需要开启缓存,可以指定value即数据缓存存在包名,key属性指定存储时key值@CachePut(value = "Student",key = "args[0].id")
指定该方法进行更新操作后将数据在redis内存中也进行更新@CacheEvict
表示进行数据删除时对redis内存中数据也进行删除@CacheXX
内key设置支持表达式设置,具体参见:Spring缓存注解@Cacheable