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)

只查询了一次数据库。

三、缓存注解

  1. @CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = "student"):配置了该数据访问对象中返回的内容将存储于名为student的缓存对象中,我们也可以不使用该注解,直接通过@Cacheable自己配置缓存集的名字来定义;

  2. @Cacheable:配置了findStudentBySno函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数:

    • valuecacheNames:两个等同的参数(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接口来实现自己的缓存解析器,并用该参数指定;

  3. @CachePut:配置于函数上,能够根据参数定义条件来进行缓存,其缓存的是方法的返回值,它与@Cacheable不同的是,它每次都会真实调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析;

  4. @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

posted @ 2020-06-12 17:19  mufeng07  阅读(354)  评论(0编辑  收藏  举报