Jedis操作Redis6
测试
依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
连接测试(错误示范)
public static void main(String[] args) {
//创建jedis对象
Jedis jedis = new Jedis("192.168.150.111",6379);
//测试是否能链接到
String ping = jedis.ping();
System.out.println(ping);
}
解决方法
禁用Linux的防火墙:Linux(CentOS7)里执行命令
systemctl stop firewalld.service
redis.conf中注释掉bind 127.0.0.1 ,然后 protected-mode no
正确结果
数据类型测试
@Test
public void string(){
//批量添加
jedis.mset("k1","v1","k2","v2","k3","v3");
//批量查询(返回list)
jedis.mget("k1","k2","k3").forEach(System.out::println);
}
@Test
public void list(){
jedis.lpush("lk","lv1","lv2","lv3");
List<String> lk = jedis.lrange("lk", 0, -1);
System.out.println(lk);
}
@Test
public void set(){
jedis.sadd("sk1","sv1","sv1","sv2","sv3","sv4","sv5");
Set<String> sk1 = jedis.smembers("sk1");
System.out.println(sk1);
}
@Test
public void hash(){
jedis.hset("user","age","20");
String hget = jedis.hget("user", "age");
System.out.println(hget);
}
@Test
public void zSet(){
jedis.zadd("zk1", 100d,"zv1");
jedis.zadd("zk1", 200d,"zv2");
jedis.zadd("zk1", 50d,"zv3");
Set<String> zk1 = jedis.zrange("zk1", 0, -1);
System.out.println(zk1);
}
}
模拟手机验证码
思路
package com.fate.jedis;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.Random;
/**
* @author m
*/
public class CodeController {
Jedis jedis = new Jedis("192.168.150.111",6379);
public Boolean isCode(String code,String id) {
String rightCode = jedis.get(id + "_code");
return rightCode.equals(code);
}
public String getCode() {
Random random = new Random();
StringBuilder code = new StringBuilder();
for (int i = 0; i < 6; i++) {
int r= random.nextInt(10);
code.append(r);
}
return code.toString();
}
public String setCode(String id) {
String code = getCode();
jedis.incrBy(id,1);
String count = jedis.get(id);
if (count == null) {
jedis.setex(id,24*60*60,"1");
}else if (Integer.parseInt(count)<3){
jedis.incrBy(id,1);
jedis.setex(id+ "_code",120*2 ,code);
return code;
}else {
System.out.println("次数上限");
}
return code;
}
@Test
public void t(){
String code = setCode("18848312652");
Boolean aBoolean = isCode(code, "18848312652");
System.out.println(aBoolean);
}
}
Redis6与Spring Boot整合
引入依赖
<!-- redis整合-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
配置文件
#Redis服务器地址
spring.redis.host=192.168.150.111
#Redis服务器连接端口
spring.redis.port=6379
#Redis数据库索引(默认为0)
spring.redis.database= 0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
配置类
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* @author m
*/
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings({ "rawtypes", "unchecked" })
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
//Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String序列号配置
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key和hash的key都采用String的序列化配置
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
//value和hash的value采用Json的序列化配置
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
测试
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author m
*/
@RestController
@RequestMapping("/redisTest")
public class RedisTestController {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@GetMapping()
public String test(){
redisTemplate.opsForValue().set("name","lucy");
return (String) redisTemplate.opsForValue().get("name");
}
}
RedisTemplate
所有方法
// 配置默认序列化与反序列化工具类
1.afterPropertiesSet
// 根据参数执行相关operation操作,例如,事务
2.execute
// 执行pipelining流水线相关操作
3.executePipelined
// 执行指定connection连接的相关操作
4.executeWithStickyConnection
// 执行session内的execute方法
5.executeSession
// 创建RedisConnection代理类
6.createRedisConnectionProxy
// connection连接的预处理
7.preProcessConnection
// 结果的后处理,默认什么都不做
8.postProcessResult
// 是否向RedisCallback暴露本地连接
9.isExposeConnection
// 设置是否向RedisCallback暴露本地连接
10.setExposeConnection
// 12到26都是设置和获取相关序列化工具类
11.isEnableDefaultSerializer
12.setEnableDefaultSerializer
13.getDefaultSerializer
14.setDefaultSerializer
15.setKeySerializer
16.getKeySerializer
17.setValueSerializer
18.getValueSerializer
19.getHashKeySerializer
20.setHashKeySerializer
21.getHashValueSerializer
22.setHashValueSerializer
23.getStringSerializer
24.setStringSerializer
25.setScriptExecutor
// 27到34为私有方法,不对外提供使用
26.rawKey
27.rawString
28.rawValue
29.rawKeys
30.deserializeKey
31.deserializeMixedResults
32.deserializeSet
33.convertTupleValues
// 执行事务
34.exec
35.execRaw
// 删除操作
36.delete
// 接触链接
37.unlink
// 查看是否含有指定key
38.hasKey
39.countExistingKeys
// 设置过期时间
40.expire
41.expireAt
// 转换成字节流并向channel发送message
42.convertAndSend
// 获取过期时间
43.getExpire
// 根据传入的正则表达式返回所有的key
44.keys
// 取消指定key的过期时间
45.persist
// 移动指定的key和index到数据库中
46.move
// 从键空间随机获取一个key
47.randomKey
// 将指定key改成目标key
48.rename
// key不存在时,将指定key改成目标key
49.renameIfAbsent
// 设置存储在指定key的类型
50.type
// 检索存储在key的值的序列化版本
51.dump
// 执行Redis的restore的命令
52.restore
// 标记事务阻塞的开始
53.multi
// 丢弃所有在multi之后发出的命令
54.discard
// 观察指定key在事务处理开始即multi之后的修改情况
55.watch
// 刷新先前观察的所有key
56.unwatch
// 为key元素排序
57.sort
// 关闭客户端连接
58.killClient
// 请求连接客户端的相关信息和统计数据
59.getClientList
// 更改复制配置到新的master
60.slaveOf
// 将本机更改为master
61.slaveOfNoOne
// 64到79都是获取相对应的操作
62.opsForCluster
63.opsForGeo
64.boundGeoOps
65.boundHashOps
66.opsForHash
67.opsForHyperLogLog
68.opsForList
69.boundListOps
70.boundSetOps
71.opsForSet
72.opsForStream
73.boundStreamOps
74.boundValueOps
75.opsForValue
76.boundZSetOps
77.opsForZSet
// 设置是否支持事务
78.setEnableTransactionSupport
// 设置bean的类加载器
79.setBeanClassLoader
spring-data-redis 提供了如下功能:
-
连接池自动管理,提供了一个高度封装的“RedisTemplate”类
-
进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作 -
提供了对 key 的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即 BoundKeyOperations
BoundValueOperations
BoundSetOperations
BoundListOperations
BoundSetOperations
BoundHashOperations -
将事务操作封装,有容器控制。
-
针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)
- JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。
- StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string是“newString(bytes,charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
- JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。
- OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】
-
如果你的数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer而不是 JdkSerializationRedisSerializer。
RedisTemplate 顶层方法
- 确定给定 key 是否存在,有的话就返回 true,没有就返回 false
redisTemplate.hasKey(K key)
- 删除给定的 key
redisTemplate.delete(K key)
- 删除给定 key 的集合
redisTemplate.delete(Collection<K> keys)
- 执行 Redis 转储命令并返回结果,把key值序列化成byte[]类型
redisTemplate.dump(K key)
- 对传入的key值设置过期时间、将给定 key 的过期时间设置为日期时间戳
redisTemplate.expire(K key, long timeout, TimeUnit unit)
redisTemplate.expireAt(K key, Date date)
- 查找与给定模式匹配的所有 key ,返回的是一个没有重复的Set类型
redisTemplate.keys(K pattern)
- 将 oldKey 重命名为 newKey。
redisTemplate.rename(K oldKey, K newKey)
- 获取key值的类型
redisTemplate. type(K key)
- 仅当 newKey 不存在时,才将密钥 oldKey 重命名为 newKey。
redisTemplate.renameIfAbsent(K oldKey, K newKey)
- 随机从redis中获取一个key
redisTemplate.randomKey()
- 获取当前key的剩下的过期时间
redisTemplate.getExpire(K key)
- 获取剩余的过期时间,同时设置时间单位
redisTemplate. getExpire(K key, TimeUnit timeUnit)
- 删除 key 的过期时间
redisTemplate. persist(K key)
- 将给定的 key 移动到带有索引的数据库
redisTemplate. move(K key, int dbIndex)
RedisTemplate.opsForValue() 方法
-
设置key跟value的值
redisTemplate.opsForValue().set(K key, V value)
-
获取 key 的值
redisTemplate.opsForValue().get(Object key)
-
设置key跟value的值,同时设置过期时间
redisTemplate.opsForValue().set(K key, V value, Duration timeout)
-
在 start 和 end 之间获取键值的子字符串
redisTemplate.opsForValue().get(K key, long start, long end)
-
设置 key 的值并返回其旧值
redisTemplate.opsForValue().getAndSet(K key, V value)
-
获取多个 key
redisTemplate.opsForValue().multiGet(Collection<K> keys)
-
获取原来的key的值后在后面新增上新的字符串
redisTemplate.opsForValue().append(K key, String value)
-
增量方式增加double值
redisTemplate.opsForValue().increment(K key, double increment)
-
通过increment(K key, long delta)方法以增量方式存储long值(正值则自增,负值则自减)
redisTemplate.opsForValue().increment(K key, long increment)
-
仅当提供的 key 不存在时,才使用集合中提供的键值对将多个 key 设置为多个值。
redisTemplate.opsForValue().multiSetIfAbsent(Map<? extends K,? extends V> map)
-
使用集合中提供的键值对将多个 key 设置为多个值
Map map = new HashMap(); map.put("1","1"); map.put("2","2"); map.put("3","3"); redisTemplate.opsForValue().multiSet(Map<? extends K,? extends V> map)
-
获取指定key的字符串的长度
redisTemplate.opsForValue().size(K key)
-
用给定值覆盖从指定偏移量开始的 key 的部分
redisTemplate.opsForValue().set(K key, V value, long offset)
-
如果 key 不存在,则设置 key 以保存字符串值,存在返回false,否则返回true
redisTemplate.opsForValue().setIfAbsent(key, value)
-
重新设置key的值并加入过期时间
redisTemplate.opsForValue().set(key, value, timeout, unit)
-
将二进制第offset位值变为value
redisTemplate.opsForValue().setBit(K key, long offset, boolean value)
-
对key所储存的字符串值,获取指定偏移量上的位(bit)
redisTemplate.opsForValue().getBit(K key, long offset)
RedisTemplate.opsForHash() 方法
- 从 key 处的 hash 中获取给定 hashKey 的值,即 key field(hashKey) value
redisTemplate.opsForHash().get(H key, Object hashKey)
- 获取存储在 key 的整个 hash,即获取所有值
redisTemplate.opsForHash().entries(H key)
- 设置hash hashKey 的值
redisTemplate.opsForHash().put(H key, HK hashKey, HV value)
- 使用 m 中提供的数据将多个 hash 字段设置为多个值,即使用 map 进行赋值
redisTemplate.opsForHash().putAll(H key, Map<? extends HK,? extends HV> m)
- 仅当 hashKey 不存在时才设置 hash hashKey 的值。
redisTemplate.opsForHash().putIfAbsent(H key, HK hashKey, HV value)
- 删除给定的hash hashKeys
redisTemplate.opsForHash().delete(H key, Object... hashKeys)
- 确定给定的hash hashKey 是否存在
redisTemplate.opsForHash().hasKey(H key, Object hashKey)
- 通过给定的增量增加hash hashKey 的值
redisTemplate.opsForHash().increment(H key, HK hashKey, double increment)
redisTemplate.opsForHash().increment(H key, HK hashKey, long increment)
- 在 key 处获取 hash 的 hashKey 集(字段)
redisTemplate.opsForHash().keys(H key)
- 获取 key 的 hash 大小。
redisTemplate.opsForHash().size(H key)
- 在 key 处获取 hash 的值
redisTemplate.opsForHash().values(H key)
- 查看匹配的键值对
redisTemplate.opsForHash().scan(H key, ScanOptions options)
RedisTemplate.opsForList() 方法
- 从 key 的 list 中获取索引处的元素
redisTemplate.opsForList().index(K key, long index)
- 从 key 的 list 中获取 start 和 end 之间的元素
redisTemplate.opsForList().range(K key, long start, long end)
- 为 key 添加值
redisTemplate.opsForList().leftPush(K key, V value)
- 将值添加到 key 中
redisTemplate.opsForList().leftPushAll(K key, Collection<V> values)
- 仅当 list 存在时,才将值添加到 key 中
redisTemplate.opsForList().leftPushIfPresent(K key, V value)
- 在 pivot 之前将值添加到 key 中
redisTemplate.opsForList().leftPush(K key, V pivot, V value)
- 将值附加到 key
redisTemplate.opsForList().rightPush(K key, V value)
redisTemplate.opsForList().rightPushAll(K key, Collection<V> values)
- 在 pivot 之后将值添加到 key 中
redisTemplate.opsForList().rightPush(K key, V pivot, V value)
- 在列表元素的索引处设置值
redisTemplate.opsForList().set(K key, long index, V value)
- 删除并返回存储在 key 的列表中的第一个元素、
redisTemplate.opsForList().leftPop(K key)
redisTemplate.opsForList().leftPop(K key, Duration timeout)
redisTemplate.opsForList().leftPop(K key, long count)
redisTemplate.opsForList().leftPop(K key, long timeout, TimeUnit unit)
- 删除并返回存储在 key 的列表中的最后一个元素
redisTemplate.opsForList().rightPop(K key)
redisTemplate.opsForList().rightPop(K key, Duration timeout)
redisTemplate.opsForList().rightPop(K key, long count)
redisTemplate.opsForList().rightPop(K key, long timeout, TimeUnit unit)
- 从 sourceKey 的列表中删除最后一个元素,将其附加到 destinationKey 并返回其值
redisTemplate.opsForList().rightPopAndLeftPush(K sourceKey, K destinationKey)
redisTemplate.opsForList().rightPopAndLeftPush(K sourceKey, K destinationKey, Duration timeout)
- 从存储在 key 的列表中删除第一个 count 出现的 value
redisTemplate.opsForList().remove(K key, long count, Object value)
- 在 start 和 end 之间的元素的 key 处修剪列表
redisTemplate.opsForList().trim(K key, long start, long end)
- 获取存储在 key 的列表的大小
redisTemplate.opsForList().size(K key)
RedisTemplate.opsForSet() 方法
- 在 key 的 set 中添加给定值
redisTemplate.opsForSet().add(K key, V... values)
- 在 key 的 set 中删除给定值并返回已删除元素的数量
redisTemplate.opsForSet().remove(K key, Object... values)
- 从 key 的 set 中移除并返回一个随机成员
redisTemplate.opsForSet(). pop(K key)
- 在 key 处获取集合的大小
redisTemplate.opsForSet().size(K key)
- 检查在 key 的 set 中是否包含值
redisTemplate.opsForSet().isMember(K key, Object o)
- 返回在 key 和 otherKeys 处与所有给定 sets 相交的成员
redisTemplate.opsForSet().intersect(K key, Collection<K> otherKeys)
- 在 key 和 otherKeys 处与所有给定 sets 相交,并将结果存储在 destKey 中
redisTemplate.opsForSet().intersectAndStore(K key, Collection<K> otherKeys, K destKey)
- 在 key 和 otherKey 处相交所有给定的 sets,并将结果存储在 destKey 中
redisTemplate.opsForSet().intersectAndStore(K key, K otherKey, K destKey)
- 合并给定 key 和 otherKey 的所有 sets
redisTemplate.opsForSet().union(K key, K otherKey)
- 将给定 key 和 otherKey 处的所有 set 合并,并将结果存储在 destKey 中
redisTemplate.opsForSet().unionAndStore(K key, K otherKey, K destKey)
- 获取差集
redisTemplate.opsForSet().difference(key, otherKeys)
- 获取差集并存储到destKey
redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey)
- 随机获取集合中的一个元素
redisTemplate.opsForSet().randomMember(key)
- 获取集合中的所有元素
redisTemplate.opsForSet().members(key)
1
- 随机获取集合中count个值
redisTemplate.opsForSet().randomMembers(key, count)
- 随机获取集合中count个值,但是去重
redisTemplate.opsForSet().distinctRandomMembers(key, count)
- 遍历set
redisTemplate.opsForSet().scan(key, options)
RedisTemplate.opsForZSet() 方法
- 添加元素,从小到大排序
redisTemplate.opsForZSet().add(key, value, score)
- 删除多个values的值
redisTemplate.opsForZSet().remove(key, values)
- 增加元素的score值同时返回增加后的值
redisTemplate.opsForZSet().incrementScore(key, value, delta)
- 返回元素在集合的从小到大排名
redisTemplate.opsForZSet().rank(key, value)
- 返回元素在集合的由大到小排名
redisTemplate.opsForZSet().reverseRank(key, value)
- 获取集合中指定区间的元素
redisTemplate.opsForZSet().reverseRangeWithScores(key, start,end)
- 查询集合中的元素并从小到大排序
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max)
redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max)
- 从高到低的排序,然后获取最小与最大值之间的值
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end)
- 根据score值获取元素数量
redisTemplate.opsForZSet().incrementScore(key, value, delta)
- 获取集合的大小
redisTemplate.opsForZSet().size(key)redisTemplate.opsForZSet().zCard(key)
- 获取集合中key、value元素的score值
redisTemplate.opsForZSet().score(key, value)
- 移除指定索引元素
redisTemplate.opsForZSet().removeRange(key, start, end)
- 移除指定score范围的集合成员
redisTemplate.opsForZSet().removeRangeByScore(key, min, max)
- 获取key和otherKey的并集并存储在destKey中
redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey)
- 获取key和otherKey的交集并存储在destKey中
redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey)