• 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

  • 相关阅读:
    Centos7-两台Centos机器间复制文件
    Centos7-卸载自带的jdk 安装jdk8
    java网络编程_IP地址
    多线程下单例模式的实现_ThreadLocal_ReentrantLock
    线程定时调度
    线程通信
    线程同步学习一
    java线程学习2
    java线程学习1
    工单系统的设计与实现(3)
  • 原文地址:https://www.cnblogs.com/mufeng07/p/13100691.html
Copyright © 2020-2023  润新知