SpringBoot自学好几天 中途开始写笔记 SpringBoot与缓存 JRS-107 SpringBoot缓存抽象 整合Redis 20190227
一、搭建redis环境 docker
- 下载镜像 可以用镜像加速(https://www.docker-cn.com/registry-mirror)
docker pull registry.docker-cn.com/library/镜像
例如: docker pull registry.docker-cn.com/library/redis
2. docker images 查看镜像
3. 启动
docker run -d -p 6379:6379 --name myredis registry.docker-cn.com/library/redis
- 测试RedisDesktopManager
- 简单测试redis常用操作
点击console 会出现命令框
存入数据:
list测试
set测试
二、缓存RedisTemplete 序列化机制
- 引入redis的sstarter点击查看地址
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
引入之后redis自动配置类就起作用了
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
自动配置文件给容器中添加了两个操作redis的方法
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
- 配置redis
spring.redis.host=192.168.2.118
- 测试
@Autowired
RedisTemplate redisTemplate;//操作对象
@Autowired
StringRedisTemplate stringRedisTemplate;//操作字符串
/**redis常见的五大数据类型
* String(字符串) List(列表) Set(集合) Hash(散列) ZSet(有序集合)
*/
@Test
public void contextLoads() {
//redis保存数据
stringRedisTemplate.opsForValue().append("msg","你好啊");
}
测试list
@Test
public void contextLoads() {
//redis保存数据
//stringRedisTemplate.opsForValue().append("msg","你好啊");
//String msg = stringRedisTemplate.opsForValue().get("msg");
//System.out.println(msg); //输出结果:你好啊
stringRedisTemplate.opsForList().leftPush("mylist","1");
stringRedisTemplate.opsForList().leftPush("mylist","2");
stringRedisTemplate.opsForList().leftPush("mylist","3");
//命令行的操作 这里几乎都能用!!!
}
测试存储对象
package com.example.cache.bean;
import java.io.Serializable;
/**
* @author LM
* @create 2019-02-25 20:51
* 对象要实现 implements Serializable
*/
public class Employee implements Serializable {
private Integer id;
private String lastName;
private String email;
private Integer gender; //性别 1男 0女
private Integer dId;
public Employee() {
super();
}
public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
super();
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.dId = dId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getdId() {
return dId;
}
public void setdId(Integer dId) {
this.dId = dId;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
+ dId + "]";
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootCacheApplicationTests {
@Autowired
RedisTemplate redisTemplate;//操作对象
@Autowired
StringRedisTemplate stringRedisTemplate;//操作字符串
@Autowired
EmployeeMapper employeeMapper ;
@Test
public void testObj(){
Employee e = employeeMapper.getEmpById(1);
redisTemplate.opsForValue().set("emp-01",e);
}
}
太乱不好 想用json格式保存???
- 自己将数据转换成json格式
- redisTemplete默认序列化规则 用的就是JDK的序列化器 换成json的就行了
package com.example.cache.config;
import com.example.cache.bean.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.net.UnknownHostException;
/**
* @author LM
* @create 2019-02-27 21:29
*/
@Configuration //配置类
public class MyRedisTemplete {
@Bean //写自己的序列化
public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Employee> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//自定义序列化器
Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
template.setDefaultSerializer(serializer);
return template;
}
}
测试自定义RedisTemplete
package com.example.cache;
import com.example.cache.bean.Employee;
import com.example.cache.mapper.EmployeeMapper;
import org.junit.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;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootCacheApplicationTests {
@Autowired
RedisTemplate redisTemplate;//操作对象
@Autowired
StringRedisTemplate stringRedisTemplate;//操作字符串
@Autowired
EmployeeMapper employeeMapper ;
@Autowired
RedisTemplate<Object, Employee> empRedisTemplate;
@Test
public void testObj(){
Employee e = employeeMapper.getEmpById(1);
empRedisTemplate.opsForValue().set("emp-01",e);
}
}
三、缓存 自定义CacheManager
原理:CacheManager 创建 Cache ,Cache 组件实际给缓存中存取数据
- 引入redis的starter的时候 容器中保存的是RedisCacheManager
- RedisCacheManager 帮我们创建RedisCache作为缓存组件 RedisCache操作redis数据
- 默认保存数据k-v 都是对象的时候 利用序列化来保存的 如何保存json???
- 自定义CacheManager
package com.example.cache.config;
import com.example.cache.bean.Employee;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
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 org.springframework.data.redis.serializer.RedisSerializer;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.LinkedHashSet;
import java.util.List;
/**
* @author LM
* @create 2019-02-27 21:29
*/
@Configuration
public class MyRedisTemplete {
@Bean
public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Employee> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//自定义序列化器
Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
template.setDefaultSerializer(serializer);
return template;
}
/**
* 自定义redis缓存管理器
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//设置CacheManager的值序列化方式为json序列化
RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(jsonSerializer);
RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(pair);
//设置默认超过期时间是30秒
defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
//初始化RedisCacheManager
return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
}
}
缓存结果:
1.0版本是不一样的 1.0需要每个实体定义一个CacheManager 然后在缓存的时候类上或者是方法上指定使用哪个 cacheManager,而且还要指定默认的cacheManager (@Primary)
注:我们还可以使用api 直接在代码里获取Cache 然后进行数据操作