springboot使用redis缓存
一、准备
pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- mybatis的启动器 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 通用mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>启动类
@SpringBootApplication
@Slf4j
@MapperScan("com.mufeng.redis.mapper")
public class StartRedisApplication {
public static void main(String[] args) {
SpringApplication.run(StartRedisApplication.class,args);
log.info("boot-redis start success....");
}
}测试类
@Test
public void test2(){
Student student=studentService.findStudentBySno("112");
System.out.println(student);
Student student1=studentService.findStudentBySno("112");
System.out.println(student1);
}结果日志:
2020-06-12 15:57:11.923 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Preparing: SELECT sno,sname,ssex,sbirthday,sclass FROM student WHERE sno = ? 2020-06-12 15:57:11.954 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Parameters: 112(String) 2020-06-12 15:57:12.307 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : <== Total: 1 Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032) 2020-06-12 15:57:12.317 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Preparing: SELECT sno,sname,ssex,sbirthday,sclass FROM student WHERE sno = ? 2020-06-12 15:57:12.317 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Parameters: 112(String) 2020-06-12 15:57:12.319 DEBUG 1308 --- [ main] c.m.r.m.I.selectByPrimaryKey : <== Total: 1 Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032)
没有使用缓存,会去查询两次数据库。
二、使用缓存
pom文件增加 spring-boot-starter-cache
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>步骤:
1.启动类添加注解@EnableCaching,开启缓存
2.在IStudentService接口添加缓存注解
@CacheConfig(cacheNames = "student")
public interface IStudentService {
@Cacheable(key = "#p0")
Student findStudentBySno(String s);
}3.测试结果:
2020-06-12 16:27:23.524 DEBUG 12976 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Preparing: SELECT sno,sname,ssex,sbirthday,sclass FROM student WHERE sno = ? 2020-06-12 16:27:23.558 DEBUG 12976 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Parameters: 112(String) 2020-06-12 16:27:23.591 DEBUG 12976 --- [ main] c.m.r.m.I.selectByPrimaryKey : <== Total: 1 Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032) Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032)
只查询了一次数据库。
三、缓存注解
@CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = "student"):配置了该数据访问对象中返回的内容将存储于名为student的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义;@Cacheable:配置了findStudentBySno函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了;key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache;condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存;unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断;keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定;cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用;cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定;
@CachePut:配置于函数上,能够根据参数定义条件来进行缓存,其缓存的是方法的返回值,它与@Cacheable不同的是,它每次都会真实调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析;@CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable一样的参数之外,它还有下面两个参数:
allEntries:非必需,默认为false。当为true时,会移除所有数据;beforeInvocation:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。
四、使用redis缓存
pom文件添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>1.application.yml添加redis连接源
2.添加redis缓存管理器配置类
@Configuration
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
//对象的序列化
RedisSerializationContext.SerializationPair valueSerializationPair
= RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer());
//全局redis缓存过期时间
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1L))
// .serializeKeysWith()
.serializeValuesWith(valueSerializationPair);
return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), redisCacheConfiguration);
}
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper());
return jackson2JsonRedisSerializer;
}
private ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
return objectMapper;
}
}3.测试类运行结果:
2020-06-12 17:04:21.393 DEBUG 8292 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Preparing: SELECT sno,sname,ssex,sbirthday,sclass FROM student WHERE sno = ? 2020-06-12 17:04:21.425 DEBUG 8292 --- [ main] c.m.r.m.I.selectByPrimaryKey : ==> Parameters: 112(String) 2020-06-12 17:04:21.507 DEBUG 8292 --- [ main] c.m.r.m.I.selectByPrimaryKey : <== Total: 1 Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032) Student(sno=112, sname=小明, ssex=男, sbirthday=Wed Mar 18 02:19:12 CST 2020, sclass=95032)
redis中存在了key:student::112

源码链接:https://github.com/mufeng07/boot/tree/master/boot-redis