• SpringBoot 整合篇 笔记--Spring Boot与缓存


    Spring Boot与缓存 

    缓存-JSR107 

      Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry Expiry

    • CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider
    • CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
    • Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
    • Entry是一个存储在Cache中的key-value对。
    • Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的

    缓存-Spring缓存抽象

    Spring从3.1开始定义了org.springframework.cache.Cache
    和org.springframework.cache.CacheManager接口来统一不同的缓存技术;
    并支持使用JCache(JSR-107)注解简化我们开发;

    Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
    Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache等;

    每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;

    如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
    使用Spring缓存抽象时我们需要关注以下两点;
    1、确定方法需要被缓存以及他们的缓存策略
    2、从缓存中读取之前缓存存储的数据

    缓存-几个重要概念&缓存注解

     

     

    缓存-缓存使用 

     初试缓存Cache:

    项目结构

    启动类:

    package com.example.testcache;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @MapperScan(value = "com.example.testcache.mapper")  //配置所有的Mapper
    @SpringBootApplication
    @EnableCaching//开启缓存
    public class TestcacheApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(TestcacheApplication.class, args);
        }
    
    }
    TestcacheApplication

    配置文件:

    spring.datasource.url=jdbc:mysql://localhost:3306/test_cache?serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=root
    #spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    # 开启驼峰命名匹配规则
    mybatis.configuration.map-underscore-to-camel-case=true
    
    logging.level.com.example.testcache.mapper=debug
    #
    #debug=true
    #
    spring.redis.host=10.87.18.41
    application.properties

    Controller:

    package com.example.testcache.controller;
    
    import com.example.testcache.bean.Department;
    import com.example.testcache.bean.Employee;
    import com.example.testcache.mapper.DepartmentMapper;
    import com.example.testcache.mapper.EmployeeMapper;
    import com.example.testcache.service.DeptService;
    import com.example.testcache.service.EmployeeService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    //import com.example.testmybatis.mapper.EmployeeMapper;
    
    @RestController
    public class DeptController {
    
        @Autowired
        DepartmentMapper departmentMapper;
    
        @Autowired
        EmployeeMapper employeeMapper;
    
        @Autowired
        EmployeeService employeeService;
    
    
        @Autowired
        DeptService deptService;
    
    
        @GetMapping("/dept/{id}")
        public Department getDepartment(@PathVariable("id") Integer id){
            return deptService.getDeptById(id);
        }
    
        @GetMapping("/dept")
        public Department insertDept(Department department){
            departmentMapper.insertDept(department);
            return department;
        }
    
        @GetMapping("/emp/{id}")
        public Employee getEmp(@PathVariable("id") Integer id){
            return employeeService.getEmpById(id);
        }
        @GetMapping("/emp")
        public Employee updateEmp(Employee employee){
            return employeeService.updateEmp(employee);
        }
    
        @GetMapping("/del/{id}")
        public String deleteEmp(@PathVariable("id") Integer id){
            employeeService.deleteEmp(id);
            return "success";
        }
    
        @GetMapping("/emp/lastName/{lastName}")
        public Employee getEmpByLastName(@PathVariable("lastName") String lastName){
            return  employeeService.getEmpByLastName(lastName);
        }
    
    }
    DeptController

    Mapper:

    package com.example.testcache.mapper;
    
    import com.example.testcache.bean.Department;
    import org.apache.ibatis.annotations.*;
    
    
    //指定这是一个操作数据库的mapper
    @Mapper
    public interface DepartmentMapper {
    
        @Select("select * from department where id=#{id}")
        public Department getDeptById(Integer id);
    
        @Delete("delete from department where id=#{id}")
        public int deleteDeptById(Integer id);
    
        @Options(useGeneratedKeys = true,keyProperty = "id")
        @Insert("insert into department(department_name) values(#{departmentName})")
        public int insertDept(Department department);
    
        @Update("update department set department_name=#{departmentName} where id=#{id}")
        public int updateDept(Department department);
    }
    DepartmentMapper
    package com.example.testcache.mapper;
    
    
    import com.example.testcache.bean.Employee;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
    
    //@Mapper或者@MapperScan将接口扫描装配到容器中
    @Mapper
    public interface EmployeeMapper {
        @Select("select * from employee where id=#{id}")
        public Employee getEmpById(Integer id);
    
        @Select("select * from employee where lastName=#{lastName}")
        public Employee getEmpByLastName(String lastName);
    
        @Update("update employee set lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} where id=#{id}")
        public void updateEmp(Employee employee);
    
        @Delete("delete from employee where id=#{id}")
        public int deleteEmp(Integer id);
    
    }
    EmployeeMapper

    Service: 

    package com.example.testcache.service;
    
    import com.example.testcache.bean.Department;
    import com.example.testcache.bean.Employee;
    import com.example.testcache.mapper.DepartmentMapper;
    import com.example.testcache.mapper.EmployeeMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.cache.Cache;
    import org.springframework.cache.annotation.*;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.stereotype.Service;
    
    @CacheConfig(cacheNames="dept"/*,cacheManager = "employeeCacheManager"*/) //抽取缓存的公共配置
    @Service
    public class DeptService {
        @Autowired
        DepartmentMapper departmentMapper;
        @Qualifier("empoyeeCacheManager")
        @Autowired
        private RedisCacheManager empoyeeCacheManager;
        /**
         * 主要针对方法配置,能够根据方法的请求参数对其结果进行缓
         **/
    //    @Cacheable(cacheNames = {"dept"})
    //    @Cacheable(cacheNames = {"dept"},key="#root.methodName+'['+#id+']'")  //自定义Key
    //    @Cacheable(cacheNames = {"dept"}, keyGenerator="myKeyGenerator")  //自定义Key生成器:
    //    @Cacheable(cacheNames = {"dept"}, keyGenerator="myKeyGenerator" ,condition = "#a0>1",unless = "#a0 == 2")  //自定义Key生成器 判断 >1:
        public Department getDeptById(Integer id){
            // 内部编码方式
            Department department = departmentMapper.getDeptById(id);
            Cache dept = empoyeeCacheManager.getCache("dept");
            dept.put("dept:1",department);
            System.out.println("部门查询");
            return department;
        }
    
    }
    DeptService
    package com.example.testcache.service;
    
    import com.example.testcache.bean.Employee;
    import com.example.testcache.mapper.EmployeeMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.*;
    import org.springframework.stereotype.Service;
    @CacheConfig(cacheNames="employee"/*,cacheManager = "employeeCacheManager"*/) //抽取缓存的公共配置
    @Service
    public class EmployeeService {
        @Autowired
        EmployeeMapper employeeMapper;
        /**
         * 主要针对方法配置,能够根据方法的请求参数对其结果进行缓
         **/
    //    @Cacheable(cacheNames = {"employee"})
        @Cacheable(cacheNames = {"employee"},key="#root.methodName+'['+#id+']'")  //自定义Key
    //    @Cacheable(cacheNames = {"employee"}, keyGenerator="myKeyGenerator")  //自定义Key生成器:
    //    @Cacheable(cacheNames = {"employee"}, keyGenerator="myKeyGenerator" ,condition = "#a0>1",unless = "#a0 == 2")  //自定义Key生成器 判断 >1:
        public Employee getEmpById(Integer id){
            Employee employee = employeeMapper.getEmpById(id);
            System.out.println("员工查询");
            return employee;
        }
    
        /**
         * 保证方法被调用,又希望结果被缓存。
         **/
        @CachePut(value ="employee",key = "#employee.id")//key = "#employee.id":使用传入的参数的员工id
    //    @CachePut(value ="employee",key = "#result.id")// key = "#result.id":使用返回结果集后的id
        public Employee updateEmp(Employee employee){
            System.out.println("updateEmp:"+employee);
            employeeMapper.updateEmp(employee);
            return employee;
        }
    
        /**
         * 清空缓存
         **/
        @CacheEvict(value="employee",key = "#id") //删除指定key
    //    @CacheEvict(value="employee",key = "#id", allEntries = true) //删除指定key  allEntries = true:指定清除这个缓存中所有的数据
    //    @CacheEvict(value="employee",beforeInvocation = true/*key = "#id",*/) //删除指定key  beforeInvocation   代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
        public void deleteEmp(Integer id){
            System.out.println("deleteEmp:"+id);
    //        employeeMapper.deleteEmp(id);
            int i = 10/0;
        }
    
    
        // @Caching 定义复杂的缓存规则
        @Caching(
                cacheable = {
                        @Cacheable(value="employee",key = "#lastName")  //员工名字
                },
                put = {
                        @CachePut(value="employee",key = "#result.id"),//员工ID
                        @CachePut(value="employee",key = "#result.email")//员工邮箱
                }
        )
        public Employee getEmpByLastName(String lastName){
            return employeeMapper.getEmpByLastName(lastName);
        }
    }
    EmployeeService

    @Cacheable:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

    原理

    将方法的运行结果进行缓存;以后再要相同的数据,直接从缓存中获取,不用调用方法;
    CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;
    
    
    
    原理:
      1、自动配置类;CacheAutoConfiguration
      2、缓存的配置类
      org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
      org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
      org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
      org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
      org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
      org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
      org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
      org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
      org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration
      org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】
      org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
      3、哪个配置类默认生效:SimpleCacheConfiguration;
    原理

    运行流程

    4、给容器中注册了一个CacheManager:ConcurrentMapCacheManager
    5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用将数据保存在ConcurrentMap中;
    
    运行流程:
    @Cacheable:
    1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;
       (CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
    2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;
       key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key;
           SimpleKeyGenerator生成key的默认策略;
                   如果没有参数;key=new SimpleKey();
                   如果有一个参数:key=参数的值
                   如果有多个参数:key=new SimpleKey(params);
    3、没有查到缓存就调用目标方法;
    4、将目标方法返回的结果,放进缓存中
    
    @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,
    如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据;
    
    核心:
       1)、使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件
       2)、key使用keyGenerator生成的,默认是SimpleKeyGenerator
    
    
    几个属性:
       cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;
    
       key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值  1-方法的返回值
               编写SpEL; #i d;参数id的值   #a0  #p0  #root.args[0]
               getEmp[2]
    
       keyGenerator:key的生成器;可以自己指定key的生成器的组件id
               key/keyGenerator:二选一使用;
    
    
       cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
    
       condition:指定符合条件的情况下才缓存;
               ,condition = "#id>0"
           condition = "#a0>1":第一个参数的值》1的时候才进行缓存
    
       unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
               unless = "#result == null"
               unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
       sync:是否使用异步模式
    View Code

    自定义Key生成器:

    package com.example.testcache.config;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration; 
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    @Configuration
    public class MyCacheConfig{
        @Bean("myKeyGenerator")
        public KeyGenerator keyGenerator(){
            return new KeyGenerator(){
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    return method.getName()+"["+ Arrays.asList(params).toString()+"]";
                }
            };
        }
    }
    MyCacheConfig

    @CachePut:保证方法被调用,又希望结果被缓存。

      /**
         * @CachePut:既调用方法,又更新缓存数据;同步更新缓存
         * 修改了数据库的某个数据,同时更新缓存;
         * 运行时机:
         *  1、先调用目标方法
         *  2、将目标方法的结果缓存起来
         *
         * 测试步骤:
         *  1、查询1号员工;查到的结果会放在缓存中;
         *          key:1  value:lastName:张三
         *  2、以后查询还是之前的结果
         *  3、更新1号员工;【lastName:zhangsan;gender:0】
         *          将方法的返回值也放进缓存了;
         *          key:传入的employee对象  值:返回的employee对象;
         *  4、查询1号员工?
         *      应该是更新后的员工;
         *          key = "#employee.id":使用传入的参数的员工id;
         *          key = "#result.id":使用返回后的id
         *             @Cacheable的key是不能用#result
         *      为什么是没更新前的?【1号员工没有在缓存中更新】
         *
         */
        @CachePut(value ="employee",key = "#employee.id")//key = "#employee.id":使用传入的参数的员工id
    //    @CachePut(value ="employee",key = "#result.id")// key = "#result.id":使用返回结果集后的id
        public Employee updateEmp(Employee employee){
            System.out.println("updateEmp:"+employee);
            employeeMapper.updateEmp(employee);
            return employee;
        }
    View Code

    @CacheEvict:清空缓存

     key:指定要清除的数据
     allEntries = true:指定清除这个缓存中所有的数据
     beforeInvocation = false:缓存的清除是否在方法之前执行
         默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除

     beforeInvocation = true:
         代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除

        /**
         * 清空缓存
         **/
        @CacheEvict(value="employee",key = "#id") //删除指定key
    //    @CacheEvict(value="employee",key = "#id", allEntries = true) //删除指定key  allEntries = true:指定清除这个缓存中所有的数据
    //    @CacheEvict(value="employee",beforeInvocation = true/*key = "#id",*/) //删除指定key  beforeInvocation   代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
        public void deleteEmp(Integer id){
            System.out.println("deleteEmp:"+id);
    //        employeeMapper.deleteEmp(id);
            int i = 10/0;
        }
    View Code

    @Caching:定义复杂的缓存规则

    @Caching(
                cacheable = {
                        @Cacheable(value="employee",key = "#lastName")  //员工名字
                },
                put = {
                        @CachePut(value="employee",key = "#result.id"),//员工ID
                        @CachePut(value="employee",key = "#result.email")//员工邮箱
                }
        )
        public Employee getEmpByLastName(String lastName){
            return employeeMapper.getEmpByLastName(lastName);
        }
    View Code

    @EnableCaching:开启基于注解的缓存  参考Controller层

    @CacheConfig:抽取缓存的公共配置 

    @CacheConfig(cacheNames="employee"/*,cacheManager = "employeeCacheManager"*/) //抽取缓存的公共配置
    @Service
    public class EmployeeService {

    注意:使用异步不支持unless

    缓存-整合redis实现缓存 

    引入spring-boot-starter-data-redis
    application.yml配置redis连接地址
    使用RestTemplate操作redis
    redisTemplate.opsForValue();  //操作字符串
    redisTemplate.opsForHash();  //操作hash
    redisTemplate.opsForList();     //操作list
    redisTemplate.opsForSet();     //操作set
    redisTemplate.opsForZSet();   //操作有序set
    配置缓存、CacheManagerCustomizers
    测试使用缓存、切换缓存、 CompositeCacheManager

     安装镜像:

     连接:

    引入redis启动器:

    官网:

    <!-- 引入redis --> 
    <dependency>
                 <groupId>org.springframework.boot</groupId> 
                 <artifactId>spring-boot-starter-data-redis</artifactId>
     </dependency>                

    配置redisConfig:

    package com.example.testcache.config;
    
    import com.example.testcache.bean.Employee;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    
    import java.time.Duration;
    
    @Configuration
    public class MyRedisConfig {
        @Bean
        public RedisTemplate<Object, Employee> empredisTemplate(RedisConnectionFactory redisConnectionFactory) throws Exception {
            RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
            template.setConnectionFactory(redisConnectionFactory);
            Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
            template.setDefaultSerializer(ser);
            return template;
        }
    
        @Bean
        public RedisCacheManager empoyeeCacheManager(RedisConnectionFactory factory) {
            RedisCacheConfiguration cacheConfiguration =
                    RedisCacheConfiguration.defaultCacheConfig()
                            .entryTtl(Duration.ofDays(1)) //失效时间
                            .disableCachingNullValues()   //序列化
                            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
                                    GenericJackson2JsonRedisSerializer()));
            return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
    
        }
    }
    MyRedisConfig

    问题1:

      存入redis 的数据,没有序列化?

    解决:

     将数据以json储存:

      方法1:将数据直接转成json

      方法2:在配置类配置序列化规则,加入容器

    package com.example.testcache;
    
    import com.example.testcache.bean.Employee;
    import com.example.testcache.mapper.EmployeeMapper;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.io.Serializable;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    class TestcacheApplicationTests{
    
        @Autowired
        EmployeeMapper employeeMapper;
        @Autowired
        StringRedisTemplate stringRedisTemplate;//操作k-v字符串
        @Autowired
        RedisTemplate redisTemplate;//k-v都是对象
    
        @Autowired
        RedisTemplate<Object,Employee> employeeRedisTemplate;//k-v都是对象
        @Test
        public void contextLoads() {
            Employee employee=employeeMapper.getEmpById(1);
            System.out.println("Message="+employee);
        }
        /**Redis常见的五大数据类型
         * String(字符串〕、List(列表)、set(集合)、Hash(散列)、ZSet(有序集合)
         * stringRedisTemplate.opsForValue()[String(字符串〕]
         * stringRedisTemplate.opsForList()[List(列表)]
         * stringRedisTemplate.opsForHash()[set(集合)]
         * stringRedisTemplate.opsForSet()[Hash(散列)]
         * stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
         * */
        @Test
        public void testRedis(){
            stringRedisTemplate.opsForValue().append("msg","hello");
    //        String msg = stringRedisTemplate.opsForValue().get("msg");
    //        System.out.println("Message="+msg);
    //        stringRedisTemplate.opsForList().leftPush("mylist","1");
    //        stringRedisTemplate.opsForList().leftPush("mylist","2");
        }
    
        @Test
        public void testObjectRedis(){
            Employee employee=employeeMapper.getEmpById(1);
            redisTemplate.opsForValue().set("emp-01",employee);
        }
    
    }
    TestcacheApplicationTests

    结果:

    直接使用缓存管理器

      @Bean
        public RedisCacheManager empoyeeCacheManager(RedisConnectionFactory factory) {
            RedisCacheConfiguration cacheConfiguration =
                    RedisCacheConfiguration.defaultCacheConfig()
                            .entryTtl(Duration.ofDays(1)) //失效时间
                            .disableCachingNullValues()   //序列化
                            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
                                    GenericJackson2JsonRedisSerializer()));
            return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
    
        }

    问题2:版本不一致,导致无法序列化?

    解决:

    在springboot1.0 和springboot2.0 中默认的序列化都是使用的jdk的 Serializer  实现这个接口,jdk自带的序列化方法

    在springboot1.0中如果向自定义我们呢直接创建cachemanager 然后传入redistemple模板对象, 就可以了, redistemple 模板对象中定制序列化的方式

        @Bean
        public RedisTemplate<Object, Employee> empRedisTemplate(
                RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
            template.setConnectionFactory(redisConnectionFactory);
            Jackson2JsonRedisSerializer<Employee> ser = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
            template.setDefaultSerializer(ser);
            return template;
        }
        @Bean
        public RedisCacheManager employeeCacheManager(RedisTemplate<Object, Employee> empRedisTemplate){
            RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);
            //key多了一个前缀
     
            //使用前缀,默认会将CacheName作为key的前缀
            cacheManager.setUsePrefix(true);
     
            return cacheManager;
        }

    springboot2.0 中,使用rediscachemanager 就可以了

     @Bean
        public RedisCacheManager empoyeeCacheManager(RedisConnectionFactory factory) {
            RedisCacheConfiguration cacheConfiguration =
                    RedisCacheConfiguration.defaultCacheConfig()
                            .entryTtl(Duration.ofDays(1)) //失效时间
                            .disableCachingNullValues()   //序列化
                            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
                                    GenericJackson2JsonRedisSerializer()));
            return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();
    
        }
  • 相关阅读:
    POJ
    POJ
    BZOJ
    HDU
    codeforces
    BZOJ
    SPOJ
    SPOJ
    SPOJ
    HDU
  • 原文地址:https://www.cnblogs.com/denghy-301/p/13042207.html
Copyright © 2020-2023  润新知