赞
踩
对于刚接触Spring boot data-redis 的同学,与jedis的关系很容易搞混,这里对data-redis于jedis做一个简单的说明,并提供整合方式
jedis是redis的java客户端,通过它可以对redis进行操作。与之功能相似的还包括:Lettuce等。
spring-data-redis
它依赖jedis或Lettuce,实际上是对jedis这些客户端的封装,提供一套与客户端无关的api供应用使用,从而你在从一个redis客户端切换为另一个客户端,不需要修改业务代码。
spring boot 整合data redis (默认依赖Lettuce)
spring-boot-data-redis 内部实现了对Lettuce和jedis两个客户端的封装,默认使用的是Lettuce
spring-boot-data-redis 内部实现了对Lettuce和jedis两个客户端的封装,默认使用的是Lettuce
使用RedisTemplate
(RedisTemplate是SpringDataRedis中对JedisApi的高度封装。
SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--com/fasterxml/jackson/core/JsonProcessingException-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/master1?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver redis: #redis服务器地址 host: 88.88.88.142 #redis服务器端口 port: 6379 #服务密码 password: #连接数 #超时时间 timeout: 10000ms lettuce: pool: #最大连接数 默认为8 max-active: 1024 #最小空闲连接 默认0 max-wait: 10000ms #最大空闲连接 默认8 max-idle: 200 #最大连接阻塞等待时间 min-idle: 5 logging: level: com.xkcoding: debug com.xkcoding.orm.mybatis.mapper: trace server: port: 8080 mybatis: type-aliases-package: com.orm.mybatis.redis.entity mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true
用来创建RedisTemplate或者StringRedisTemplate对象(RedisTemplate和StringRedisTemplate的区别)
@Configuration public class RedisConfig { /** * StringRedisTemplate与RedisTemplate区别点 * 两者的关系是StringRedisTemplate继承RedisTemplate。 * * 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。 * * 其实他们两者之间的区别主要在于他们使用的序列化类: * RedisTemplate使用的是JdkSerializationRedisSerializer 存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 * * StringRedisTemplate使用的是StringRedisSerializer * * 使用时注意事项: * 当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可。 * 但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。 */ @Bean //用GenericJackson2JsonRedisSerializer来序列化 public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){ //我们为了自己开发方便,一般直接使用<String,Object> RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // 设置键(key)的序列化采用StringRedisSerializer StringRedisSerializer stringRedisSerializer=new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); // 设置值(value)的序列化采用GenericJackson2JsonRedisSerializer GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); redisTemplate.setHashValueSerializer(jsonRedisSerializer); redisTemplate.setValueSerializer(jsonRedisSerializer); //设置连接工厂 redisTemplate.setConnectionFactory(lettuceConnectionFactory); redisTemplate.afterPropertiesSet(); return redisTemplate; } // @Bean //用Jackson2JsonRedisSerializer来序列化 // public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { // //我们为了自己开发方便,一般直接使用<String,Object> // RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // // //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式) // Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class); // // ObjectMapper mapper = new ObjectMapper(); // mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // //mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 过期了 // mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , // ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // // serializer.setObjectMapper(mapper); // // redisTemplate.setValueSerializer(serializer); // //使用StringRedisSerializer来序列化和反序列化redis的key值 // StringRedisSerializer stringRedisSerializer=new StringRedisSerializer(); // redisTemplate.setKeySerializer(stringRedisSerializer); // redisTemplate.setHashKeySerializer(stringRedisSerializer); // // redisTemplate.setConnectionFactory(lettuceConnectionFactory); // // redisTemplate.afterPropertiesSet(); // return redisTemplate; // } @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); stringRedisTemplate.setConnectionFactory(factory); return stringRedisTemplate; } }
Jackson2JsonRedisSerializer和GenericJackson2JsonRedisSerializer的区别 https://blog.csdn.net/bai_bug/article/details/81222519
RedisTemplate 对五种数据结构分别定义了操作
redisTemplate.opsForValue();
操作字符串
redisTemplate.opsForHash();
操作hash
redisTemplate.opsForList();
操作list
redisTemplate.opsForSet();
操作set
redisTemplate.opsForZSet();
操作有序set
如果操作字符串的话,建议用 StringRedisTemplate 。
StringRedisTemplate 继承了 RedisTemplate。
RedisTemplate 是一个泛型类,而 StringRedisTemplate 则不是。
StringRedisTemplate 只能对 key=String,value=String 的键值对进行操作,RedisTemplate 可以对任何类型的 key-value 键值对操作。
他们各自序列化的方式不同,但最终都是得到了一个字节数组,殊途同归,StringRedisTemplate 使用的是 StringRedisSerializer 类;RedisTemplate 使用的是 JdkSerializationRedisSerializer 类。反序列化,则是一个得到 String,一个得到 Object
两者的数据是不共通的,StringRedisTemplate 只能管理 StringRedisTemplate 里面的数据,RedisTemplate 只能管理 RedisTemplate中的数据。
在启动类上加注解 @EnableCaching
@EnableCaching
@SpringBootApplication
public class SpringbootMybatisRedisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisRedisApplication.class, args);
}
}
常用的注解有以下几个
用于查询和添加缓存,第一次查询的时候返回该方法返回值,并向 Redis 服务器保存数据。
以后调用该方法先从 Redis 中查是否有数据,如果有直接返回 Redis 缓存的数据,而不执行方法里的代码。如果没有则正常执行方法体中的代码。
value 或 cacheNames 属性做键,key 属性则可以看作为 value 的子键, 一个 value 可以有多个 key 组成不同值存在 Redis 服务器。
验证了下,value 和 cacheNames 的作用是一样的,都是标识主键。两个属性不能同时定义,只能定义一个,否则会报错。
在需要加缓存的方法上添加注解
key为数字 @Cacheable(value = “user”, key = “123”)
key为英文 @Cacheable(value = “user”, key = “‘test’”)
cacheNames 和 key 都必须填,如果不填 key ,默认的 key 是当前的方法名。
下面介绍一下 @Cacheable 这个注解常用的几个属性:
属性 | 解释 |
---|---|
cacheNames/value | 用来指定缓存组件的名字 |
key | 缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写) |
keyGenerator | key 的生成器。 key 和 keyGenerator 二选一使用 |
cacheManager | 可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。 |
condition | 可以用来指定符合条件的情况下才缓存 |
unless | 否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果) |
sync | 是否使用异步模式。 |
@Cacheable(value = "user",key = "#id")
@GetMapping(value = "/get/user")
public User getUser(@RequestParam Long id){
User user = userMapper1.selectUserById(id);
System.out.println("走了DB查询"+id);
return user;
}
如果参数是个对象,也可以设置对象的某个属性为 key。比如其中一个参数是 user 对象,key 可以写成 key=“#user.id”
@Cacheable(value = "user",key = "#user.id")
@GetMapping(value = "/get/user")
public User getUser(@RequestBody User user){
User user = userMapper1.selectUserByUser(user);
System.out.println("走了DB查询"+user);
return user;
}
在需要更新缓存的方法上加注解: @CachePut(cacheNames = “user”, key = “123”)
使用CachePut注解,该方法每次都会执行,会清除对应的key值得缓存(或者更新)。
分为以下两种情况:
情况一
:如果返回值null,下次进行该key值查询时,还会查一次数据库,此时相当于@CacheEvict注解;
情况二
:如果返回值不为null,此时会进行该key值缓存的更新,更新缓存值为返回的数据;
查询方法
@Cacheable(value = "user",key = "#id")
@GetMapping(value = "/get/user")
public User getUser(@RequestParam Long id){
User user = userMapper1.selectUserById(id);
System.out.println("走了DB查询"+id);
return user;
}
更新方法
@CachePut(value = "user",key = "#user.id")
@PostMapping(value = "/update/user",produces = "application/json;charset=UTF-8")
public User updateUser(@RequestBody User user){
userMapper1.updateUserById(user);
return null;
}
相当于添加了@CacheEvict(value=“user”,key=“#user.id”)
下一次访问/get/user方法时候,会重新走一次DB,数据库查询。不走redis。
查询方法
@Cacheable(value = "user",key = "#id")
@GetMapping(value = "/get/user")
public User getUser(@RequestParam Long id){
User user = userMapper1.selectUserById(id);
System.out.println("走了DB查询"+id);
return user;
}
更新方法
@CachePut(value = "user",key = "#user.id")
@PostMapping(value = "/update/user",produces = "application/json;charset=UTF-8")
public User updateUser(@RequestBody User user){
userMapper1.updateUserById(user);
User user1 = userMapper1.selectUserById(user.getId());
return user1;
//此时进行id为1数据更新操作,返回值不为null;
//如果下次进行/get/user id为1的数据查询,发现此时id为1缓存被更新为更新的数据,且没有进行DB查询操作;
}
先进行数据id为1的查询,发现下次查询id为1的数据不会再查询DB,直接走缓存;
在需要删除缓存的方法上加注解:@CacheEvict(value= “user”, key = “123”),执行完这个方法之后会将 Redis 中对应的记录删除。
@CacheEvict还有个allEntries属性,默认为false,我们可以将其设置为,清除指定缓存中的所有缓存,这里是user (value =) 。
allEntries 是 @CacheEvict 特有的一个属性,意为是否删除整个缓存(value 或 cacheNames 指定的),默认为 false。
@CacheEvict还有个beforeInvocation属性,默认为false,表示缓存是否在方法执行之前进行清除。默认为false是在方法执行之后执行。
beforeInvocation 是 @CacheEvict 中特有的一个属性,意为是否在执行对应方法之前删除缓存,默认 false(即执行方法之后再删除缓存)。
@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
@Caching(put ={@CachePut(value = "user",key = "#user.id")},
evict = {@CacheEvict(value = "user",key = "'getUserList'"),@CacheEvict(value = "user",key = "1")})
import com.orm.mybatis.redis.entity.User; import com.orm.mybatis.redis.mapper.UserMapper1; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; @RestController public class RedisController { @Resource private UserMapper1 userMapper1; //@Cacheable用于查询和添加缓存,第一次查询的时候返回该方法返回值,并向 Redis 服务器保存数据。 //以后调用该方法先从 Redis 中查是否有数据,如果有直接返回 Redis 缓存的数据,而不执行方法里的代码。 //如果没有则正常执行方法体中的代码。 //value 或 cacheNames 属性做键,key 属性则可以看作为 value 的子键,一个 value 可以有多个 key // 组成不同值存在 Redis 服务器。 //验证了下,value 和 cacheNames 的作用是一样的,都是标识主键。两个属性不能同时定义,只能定义一个,否则会报错。 @Cacheable(value = "user",key = "#id") @GetMapping(value = "/get/user") public User getUser(@RequestParam Long id){ User user = userMapper1.selectUserById(id); System.out.println("走了DB查询"+id); return user; } @Cacheable(value = "user",key = "'getUserList'") @GetMapping(value = "/get/userList") public List<User> getUserList(){ List<User> userList = userMapper1.selectAllUser(); System.out.println("走了DB查询userList"); return userList; } //使用CachePut注解,该方法每次都会执行,会清除对应的key值得缓存(或者更新), //分为以下两种情况: //如果返回值null,下次进行该key值查询时,还会查一次数据库,此时相当于@CacheEvict注解; //如果返回值不为null,此时会进行该key值缓存的更新,更新缓存值为返回的数据; //这里会先删除value的user的所有缓存再返回该value对应的key值缓存的新增更新 @CachePut(value = "user",key = "#user.id") @CacheEvict(value = "user", allEntries = true,beforeInvocation = true) @PostMapping(value = "/update/user",produces = "application/json;charset=UTF-8") public User updateUser(@RequestBody User user){ userMapper1.updateUserById(user); User user1 = userMapper1.selectUserById(user.getId()); return user1; //此时进行id为1数据更新操作,返回值不为null; //如果下次进行/get/user id为1的数据查询,发现此时id为1缓存被更新为更新的数据, //且没有进行DB查询操作; } //在需要删除缓存的方法上加注解:@CacheEvict(cacheNames = "user", key = "#id"), //执行完这个方法之后会将user 中对所有记录删除。 // @CacheEvict(value = "user",key = "#id") @CacheEvict(value = "user",allEntries = true) @GetMapping(value = "/cancel/user") public void updateUser(@RequestParam Long id){ } //新增的数据put到缓存,删除对应的list数组的value::key的缓存,以及测试用的删除对应的key为1的缓存。 @Caching(put ={@CachePut(value = "user",key = "#user.id")}, evict = {@CacheEvict(value = "user",key = "'getUserList'"),@CacheEvict(value = "user",key = "1")}) @PostMapping(value = "/insert/user") public User insertUser(@RequestBody User user){ userMapper1.saveUser(user); System.out.println(user.getId()); User user1 = userMapper1.selectUserById(user.getId()); return user1; } }
如上方法能保证在最新访问查数据的接口时候
@Cacheable(value = “user”,key = “#id”)
@GetMapping(value = “/get/user”)
和
@Cacheable(value = “user”,key = “‘getUserList’”)
@GetMapping(value = “/get/userList”)
如果遇到增删改的话会删除或替换对应缓存,然后下次查询list时候走数据库查询或走新的缓存,而不走旧的数值的缓存。
package com.orm.mybatis.redis.utils; @Component public class RedisUtils { @Resource private RedisTemplate redisTemplate; //=======================common======================== /** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) * @return */ public boolean expire(String key,long time){ try { if(time > 0){ redisTemplate.expire(key,time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key获取过期时间 * @param key 键 不能为null * @return 时间(秒) 返回0代表永久有效 */ public long getExpire(String key){ return redisTemplate.getExpire(key,TimeUnit.SECONDS); } /** * 判断key是否存在 * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key){ try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * @param key 可以传一个或多个 */ public void del(String... key){ if(key != null && key.length > 0){ if(key.length == 1){ redisTemplate.delete(key[0]); }else{ redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通缓存获取 * @param key 键 * @return 值 */ public Object get(String key){ return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * @param key 键 * @param value 值 * @return true 成功 false 失败 */ public boolean set(String key,Object value){ try { redisTemplate.opsForValue().set(key,value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } // ============================multiSet和 multiGet============================= /** * 普通缓存获取 * @param keys 键 * @return 值 */ public List<?> multiGet(ArrayList<?> keys){ return keys == null ? null : redisTemplate.opsForValue().multiGet(keys); } /** * 普通缓存获取 * @param keys 键 * @return 值 */ public Set<?> getPattern(String pattern){ return redisTemplate.keys(pattern); } /** * * @param hashMap * @return */ public boolean multiSet(HashMap hashMap){ try { redisTemplate.opsForValue().multiSet(hashMap); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒)time小于等于0,将设置无限期 * @return true 成功 false 失败 */ public boolean set(String key,Object value,long time){ try { if(time > 0){ redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS); }else{ set(key,value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 递增 * @param key 键 * @param delta 要增加几(大于0) */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * @param key 键 * @param delta 要减少几(小于0) */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= /** * HashGet * @param key 键 不能为null * @param item 项 不能为null */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * HashGet * @param key 键 不能为null * @param items 项 不能为null */ public Object hMultiGet(String key, ArrayList<?> items) { return redisTemplate.opsForHash().multiGet(key, items); } /** * 获取hashKey对应的所有键值 * @param key 键 * @return 对应的多个键值 */ public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * @param key 键 * @param map 对应多个键值 */ public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 并设置时间 * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */ public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public boolean hset(String key, String item, String value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除hash表中的值 * * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判断hash表中是否有该项的值 * * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * * @param key 键 * @param item 项 * @param by 要增加几(大于0) */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash递减 * * @param key 键 * @param item 项 * @param by 要减少记(小于0) */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= /** * 根据key获取Set中的所有值 * @param key 键 */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据value从一个set中查询,是否存在 * * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将数据放入set缓存 * * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * @param key 键 * @return */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= /** * 获取list缓存的内容 * * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 */ public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 获取list缓存的长度 * * @param key 键 */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通过索引 获取list中的值 * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0 时,-1,表尾,-2倒数第二个元素,依次类推 */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 */ public boolean lPivotSet(String key,String pivot, Object value) { try { redisTemplate.opsForList().rightPush(key,pivot, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * //右弹出 删除右边第一个 * * @param key 键 * */ public Object lPop(String key) { try { Object value = redisTemplate.opsForList().rightPop(key); return value; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据索引修改list中的某条数据 * * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N个值为value * * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } // ============================zSet============================= /** * 根据key获取Set中的所有值 * @param key 键 */ public Set<Object> zSGet(String key, long start, long end) { try { return redisTemplate.opsForZSet().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将数据放入set缓存 * * @param key 键 * @param hashSet 值 可以是多个 * @return 成功个数 */ public long zSSet(String key, HashSet hashSet) { try { return redisTemplate.opsForZSet().add(key, hashSet); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * * @param key 键 * @param time 时间(秒) * @param hashSet 值 可以是多个 * @return 成功个数 */ public long zSSetAndTime(String key, long time, HashSet hashSet) { try { Long count = redisTemplate.opsForZSet().add(key, hashSet); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * @param key 键 * @return */ public long zSGetSetSize(String key) { try { return redisTemplate.opsForZSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long zSetRemove(String key, Object... values) { try { Long count = redisTemplate.opsForZSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } }
package com.orm.mybatis.redis; @SpringBootTest class SpringbootMybatisRedisApplicationTests { @Resource private RedisUtils redisUtils; @Resource private StringRedisTemplate stringRedisTemplate; @Test void testStringRedisTemplate(){ ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue(); stringStringValueOperations.set("age", "20"); String age = stringStringValueOperations.get("age"); System.out.println(age); } @Test void testOpsForValue(){ SimpleDateFormat format = new SimpleDateFormat(); User user = User.builder().name("andrew").password("123456") .email("123@qq.com") .phoneNumber("13719180727") .salt("123456789") .status(1) .createTime(format.format(DateUtil.now())) .build(); List<User> list = new ArrayList<>(); list.add(user); // ValueOperations<String, Object> ops = redisTemplate.opsForValue(); redisUtils.set("user", list); Object user1 = redisUtils.get("user"); List<User> list1 = (List<User>) redisUtils.get("user"); System.out.println(user1); System.out.println(list1); } @Test void testOpsForValueMulti(){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); User user1 = User.builder().name("andrew").password("123456") .email("123@qq.com") .phoneNumber("13719180727") .salt("123456789") .status(1) .createTime(format.format(DateUtil.now())) .build(); User user2 = User.builder().name("andrew1").password("123456") .email("123@qq.com") .phoneNumber("13719180727") .salt("123456789") .status(1) .createTime(format.format(DateUtil.now())) .build(); HashMap<String,User> hashMap = new HashMap<>(); hashMap.put("user1",user1); hashMap.put("user2",user2); // ValueOperations<String, Object> ops = redisTemplate.opsForValue(); redisUtils.multiSet(hashMap); ArrayList<String> keys = new ArrayList<>(); keys.add("user1"); keys.add("user2"); List<User> list1 = (List<User>) redisUtils.multiGet(keys); list1.forEach(System.out::println); redisUtils.del("user1"); List<User> list2 = (List<User>) redisUtils.multiGet(keys); list2.forEach(System.out::println); } /** * 操作hash */ @Test public void testHash() { /** * 添加的第一条数据 * redis的key * hash的key * hash的值 */ redisUtils.hset("userall", "name", "zhangsan"); /** * 获取一条数据 * 第一个参数redis的key * 第二个参数hash的key */ Object object = redisUtils.hget("userall", "name"); System.out.println(object); //添加多条数据 //存多条数据 HashMap<String, Object> map = new HashMap<>(); map.put("name", "zhangsan"); map.put("age", "14"); map.put("sex", "nan"); redisUtils.hmset("userall1", map); //获取多条数据 //把key装入结合中 ArrayList<String> keys = new ArrayList<>(); keys.add("name"); keys.add("age"); keys.add("sex"); //拿取多条数据 List user = (List) redisUtils.hMultiGet("userall1", keys); user.forEach(System.out::println); //获取hash类型的所有数据 Map<Object, Object> entries = redisUtils.hmget("userall1"); entries.forEach((key, value) -> System.out.println(key + "-->" + value)); //hash自带的删除 redisUtils.hdel("userall", "name"); //获取hash类型的所有数据 Map<Object, Object> entries1 = redisUtils.hmget("userall"); entries1.forEach((key, value) -> System.out.println(key + "-->" + value)); } /** * 操作list */ @Test public void testList() { redisUtils.del("students"); //左添加 redisUtils.lSet("students", "张三"); //第一个参数redis的key 第二个参数被左添加的数据 redisUtils.lPivotSet("students", "张三", "钱二"); redisUtils.lSet("students", "李四"); //右添加 redisUtils.lSet("students", "牛牛"); //获取数据 List students = redisUtils.lGet("students", 0, -1); students.forEach(System.out::println); //获取总条数 Long size = redisUtils.lGetListSize("students"); System.out.println(size); //删除 redisUtils.lRemove("students", 1, "张三"); //左弹出 删除右边第一个 redisUtils.lPop("students"); //右弹出 删除右边第一个 redisUtils.lPop("students"); } /** * 操作set */ @Test public void testSet() { //添加数据 String[] arr = new String[]{"aaa", "bbb", "ccc","aaa", "ddd"}; redisUtils.sSet("letters", "111", "33", "334"); redisUtils.sSet("letters", arr); //获取数据 Set letters = redisUtils.sGet("letters"); letters.forEach(System.out::println); //删除 redisUtils.setRemove("letters", "aaa", "111"); } /** * 操作sorted set */ @Test public void testSortedSet() { //添加数据 ZSetOperations.TypedTuple<Object> objectTypedTuple = new DefaultTypedTuple<>("zhangsan", 7D); ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("lisi", 2D); ZSetOperations.TypedTuple<Object> objectTypedTuple3 = new DefaultTypedTuple<>("wangwu", 9D); ZSetOperations.TypedTuple<Object> objectTypedTuple4 = new DefaultTypedTuple<>("zhaoliu", 3D); HashSet<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>(); tuples.add(objectTypedTuple); tuples.add(objectTypedTuple2); tuples.add(objectTypedTuple3); tuples.add(objectTypedTuple4); redisUtils.zSSet("score", tuples); //zSetOperations.add("name","niuniu",7D); //获取数据 Set set = redisUtils.zSGet("score", 0, -1); set.forEach(System.out::println); //总条数 Long size = redisUtils.zSGetSetSize("score"); System.out.println(size); //删除数据 redisUtils.zSetRemove("score", "zhangsan", "lisi"); } /** * 获取所有的key */ @Test public void testAllKeys() { Set keys = redisUtils.getPattern("*"); keys.forEach(System.out::println); } /** * 失效时间 */ @Test public void testExpire() { //方法一 添加key的时候设置失效时间 redisUtils.set("code", "test", 30); //方法二 给已经存在的key设置失效时间 redisUtils.set("address", "添加时未设置失效时间"); redisUtils.expire("address", 30); //查看失效时间 Long code = redisUtils.getExpire("code"); System.out.println(code); Long time = redisUtils.getExpire("address"); System.out.println(time); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。