Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。
注意: 使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口
11.1 环境准备
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置application.propertie
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0
3.创建获取工厂的工具类
//用来获取springboot创建好的工厂
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
//保留下来工厂
private static ApplicationContext applicationContext;
//将创建好工厂以参数形式传递给这个类
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//提供在工厂中获取对象的方法 //RedisTemplate redisTemplate
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
}
4.自定义Redis缓存的实现
//自定义Redis缓存实现
public class RedisCache implements Cache {
//当前放入缓存的mapper的namespace
private final String id;
//必须存在构造方法
public RedisCache(String id) {
this.id = id;
}
//返回cache唯一标识
@Override
public String getId() {
return this.id;
}
//缓存放入值 redis RedisTemplate StringRedisTemplate
@Override
public void putObject(Object key, Object value) {
System.out.println("key:" + key.toString());
System.out.println("value:" + value);
// //通过application工具类获取redisTemplate
// RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//使用redishash类型作为缓存存储模型 key hashkey value
getRedisTemplate().opsForHash().put(id.toString(),getKeyToMD5(key.toString()),value);
if(id.equals("com.baizhi.dao.UserDAO")){
//缓存超时 client 用户 client 员工
getRedisTemplate().expire(id.toString(),1, TimeUnit.HOURS);
}
if(id.equals("com.baizhi.dao.CityDAO")){
//缓存超时 client 用户 client 员工
getRedisTemplate().expire(id.toString(),30, TimeUnit.MINUTES);
}
//.....指定不同业务模块设置不同缓存超时时间
}
//获取中获取数据
@Override
public Object getObject(Object key) {
System.out.println("key:" + key.toString());
// //通过application工具类获取redisTemplate
// RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
// redisTemplate.setKeySerializer(new StringRedisSerializer());
// redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//根据key 从redis的hash类型中获取数据
return getRedisTemplate().opsForHash().get(id.toString(), getKeyToMD5(key.toString()));
}
//注意:这个方法为mybatis保留方法 默认没有实现 后续版本可能会实现
@Override
public Object removeObject(Object key) {
System.out.println("根据指定key删除缓存");
return null;
}
@Override
public void clear() {
System.out.println("清空缓存~~~");
//清空namespace
getRedisTemplate().delete(id.toString());//清空缓存
}
//用来计算缓存数量
@Override
public int getSize() {
//获取hash中key value数量
return getRedisTemplate().opsForHash().size(id.toString()).intValue();
}
//封装redisTemplate
private RedisTemplate getRedisTemplate(){
//通过application工具类获取redisTemplate
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
//封装一个对key进行md5处理方法
private String getKeyToMD5(String key){
return DigestUtils.md5DigestAsHex(key.getBytes());
}
}
4.在Mapper中开启Redis缓存
<!--开启mybatis二级缓存-->
<cache type="com.tnt.cache.RedisCache"/>
<!--关联关系缓存处理-->
<cache-ref namespace="com.tnt.dao.UserDAO"/
5.测试使用
@Autowired
private StringRedisTemplate stringRedisTemplate; //对字符串支持比较友好,不能存储对象
@Autowired
private RedisTemplate redisTemplate; //存储对象
@Test
public void testRedisTemplate(){
System.out.println(redisTemplate);
//设置redistemplate值使用对象序列化策略
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());//指定值使用对象序列化
//redisTemplate.opsForValue().set("user",new User("21","小黑",23,new Date()));
User user = (User) redisTemplate.opsForValue().get("user");
System.out.println(user);
// Set keys = redisTemplate.keys("*");
// keys.forEach(key -> System.out.println(key));
/*Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);*/
//Object xiaohei = redisTemplate.opsForValue().get("xiaohei");
//System.out.println(xiaohei);
/*redisTemplate.opsForValue().set("name","xxxx");
Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);*/
/*redisTemplate.opsForList().leftPushAll("lists","xxxx","1111");
List lists = redisTemplate.opsForList().range("lists", 0, -1);
lists.forEach(list-> System.out.println(list));*/
}
//key的绑定操作 如果日后对某一个key的操作及其频繁,可以将这个key绑定到对应redistemplate中,日后基于绑定操作都是操作这个key
//boundValueOps 用来对String值绑定key
//boundListOps 用来对List值绑定key
//boundSetOps 用来对Set值绑定key
//boundZsetOps 用来对Zset值绑定key
//boundHashOps 用来对Hash值绑定key
@Test
public void testBoundKey(){
BoundValueOperations<String, String> nameValueOperations =stringRedisTemplate.boundValueOps("name");
nameValueOperations.set("1");
//yuew
nameValueOperations.set("2");
String s = nameValueOperations.get();
System.out.println(s);
}
//hash相关操作 opsForHash
@Test
public void testHash(){
stringRedisTemplate.opsForHash().put("maps","name","小黑");
Object o = stringRedisTemplate.opsForHash().get("maps", "name");
System.out.println(o);
}
//zset相关操作 opsForZSet
@Test
public void testZSet(){
stringRedisTemplate.opsForZSet().add("zsets","小黑",10);
Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1);
zsets.forEach(value-> System.out.println(value));
}
//set相关操作 opsForSet
@Test
public void testSet(){
stringRedisTemplate.opsForSet().add("sets","xiaosan","xiaosi","xiaowu");
Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
sets.forEach(value-> System.out.println(value));
}
//list相关的操作opsForList
@Test
public void testList(){
// stringRedisTemplate.opsForList().leftPushAll("lists","张三","李四","王五");
List<String> lists = stringRedisTemplate.opsForList().range("lists", 0, -1);
lists.forEach(key -> System.out.println(key));
}
//String相关的操作 opsForValue
@Test
public void testString(){
//stringRedisTemplate.opsForValue().set("166","好同学");
String s = stringRedisTemplate.opsForValue().get("166");
System.out.println(s);
Long size = stringRedisTemplate.opsForValue().size("166");
System.out.println(size);
}
//key相关的操作
@Test
public void test(){
Set<String> keys = stringRedisTemplate.keys("*");//查看所有key
Boolean name = stringRedisTemplate.hasKey("name");//判断某个key是否存在
stringRedisTemplate.delete("age");//根据指定key删除
stringRedisTemplate.rename("","");//修改key的名称
stringRedisTemplate.expire("key",10, TimeUnit.HOURS);
//设置key超时时间 参数1:设置key名 参数2:时间 参数3:时间的单位
stringRedisTemplate.move("",1);//移动key
}