SpringBoot缓存篇Ⅱ

一.Redis环境搭建

系统默认是使用ConcurrentMapCacheManager,然后获取和创建ConcurrentMapCache类型的缓存组件,再将数据保存在ConcurrentMap中

开发中使用缓存中间件:redis,memcached,ehcache

1.搭建redis环境

在linux上安装redis(推荐使用docker)。docker安装redis的技巧:使用国内镜像可以加速下载。

docker pull registry.docker-cn.com/library/redis

2.使用docker启动redis

 docker run -p 6379:6379 --name myredis -d registry.docker-cn.com/library/redis

3.引入redis的starter

1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-data-redis</artifactId> 4</dependency>

4.配置redis

spring.redis.host=172.**.**.**

二.RedisTemplate的使用

SpringBoot底层整合了spring-data-redis,里面的StringRedisTemplate以及RedisTemplate都已经注入到容器中,使用的时候直接从容器中取出来即可。其中StringRedisTemplate封装了redis对字符串的一些常用操作,RedisTemplate封装了一些对象的常用操作。

1.StringRedisTemplate的使用

1public void testStringRedis() { 2 //redis保存数据 3 stringRedisTemplate.opsForValue().append("msg","hello"); 4 5 //读取数据 6 String msg = stringRedisTemplate.opsForValue().get("msg"); 7 System.out.println(msg); 8     //list存储数据  9 stringRedisTemplate.opsForList().leftPush("mylist","1"); 10 stringRedisTemplate.opsForList().leftPush("mylist","2"); 11 stringRedisTemplate.opsForList().leftPush("mylist","3"); 12 String mylist = stringRedisTemplate.opsForList().leftPop("mylist"); //删除并查询最顶层的list数据 13 System.out.println(mylist); 14 }

2.RedisTemplate的使用

1public void testRedis() { 2 employeeRedisTemplate.opsForValue().set("emp-02",employeeMapper.getEmployeeById(2)); 3 }

使用set方法保存查询到的员工对象,执行完毕后发现有错误,这是因为Emp对象没有被序列化,没有序列化的对象是无法存入redis数据库。所以需要Emp实体类实现Serializable接口,将对象序列化再次执行发现有数据存储到数据库中,但是是以序列化的方式存储的。

这样存储数据是有了,但是存在数据库里很不直观,查询数据的人无法知道自己存了什么数据进去,那么如何解决序列化对象的问题呢?

redis存取序列化对象的解决方式

**方式一:**将数据以json形式保存,将对象转为json,转成json对象后,就会以json的形式存储到数据库中。

**方式二:**改变默认的序列化规则,由于默认使用jdk的序列化器,切换使用json的序列化器即可解决序列化问题

1@Configuration 2public class MyRedisConfig { 3 @Bean 4 public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { 5 RedisTemplate<Object, Employee> template = new RedisTemplate(); 6 template.setConnectionFactory(redisConnectionFactory); 7 Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer(Employee.class); 8 template.setDefaultSerializer(serializer); 9 return template; 10 } 11}

使用的时候注入该类,使用这个类来调用set方法即可将Emp对象存到数据库里

1@Autowired 2RedisTemplate<Object, Employee> employeeRedisTemplate; 3 4public void testRedis() { employeeRedisTemplate.opsForValue().set("emp-02",employeeMapper.getEmployeeById(2));}

三**.测试Redis缓存**

1.默认使用ConcurrentMapCacheManager缓存组件来实际给缓存中存取数据。引入redis的starter之后,容器中保存的是RedisCacheManager,开启debug日志报告,可以搜索已经开启了的 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration,原来的SimpleCacheConfiguration将不再匹配。

2.RedisCacheManager帮我们创建RedisCache来作为缓存组件,RedisCache通过操作redis来操作缓存数据,原来的缓存替换为redis缓存,注解配置都一样,区别是缓存的内容都存到配置好的redis数据库了。

3.默认保存数据k-v都是object,利用序列化保存,所以需要反序列化,将其保存为json

  1)、引入了redis的starter,cacheManager变为RedisCacheManager

  2)、默认创建的RedisCacheManager操作redis的时候使用的是RedisTemplate<Object,Object>

  3)、RedisTemplate<Object,Object>默认使用jdk的序列化机制,所以会乱码

  4)、自定义CacheManager(springboox1.x的版本和这个有区别,这边给出的是2.x的例子)

1//容器会自动检测到这个CacheManager,并替换原来自带的CacheManager 2 @Primary //若配置多个缓存管理器需要有一个默认的缓存管理器 3 @Bean 4 public RedisCacheManager myCacheManager(RedisConnectionFactory redisConnectionFactory){ 5 RedisSerializer<String> redisSerializer = new StringRedisSerializer(); 6 //.entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时 7 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 8 9 ObjectMapper om = new ObjectMapper(); 10 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 11 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 12 jackson2JsonRedisSerializer.setObjectMapper(om); 13 14 // 配置序列化(解决乱码的问题) 15 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() 16 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) 17 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) 18 .disableCachingNullValues(); 19 20 RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory) 21 .cacheDefaults(config) 22 .build(); 23 return cacheManager; 24 }

注意多个缓存管理器时,若需要引入缓存管理器可以在类注解上@CacheConfig(cacheNames = "emp",cacheManager = "myCacheManager") 配置。

使用编码的方式进行缓存

上面讲的都是采用注解的方式进行缓存的,实际生产过程中也可以采用编码的方式进行缓存。

  1. 注入缓存管理器

    @Qualifier("myCacheManager") @Autowired RedisCacheManager myCacheManager;

  2. 编码缓存

    public Department getDept(Integer id){ Department department = departmentMapper.getDepartmentById(id); Cache dept = myCacheManager.getCache("dept"); //获取某个缓存 dept.put("dept:1",department);

    1 return departmentMapper.getDepartmentById(id); 2 }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )