一、准备
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