Redis简介 什么是Redis Redis是一款开源的内存数据库,也称为键值存储(database)、缓存(database)和消息队列(database)系统。它提供了丰富的数据结构和高效的操作方式,并且支持多种编程语言的客户端,如Java、Python、C++等,让开发人员可以轻松地使用Redis来构建高性能、可扩展的应用程序。Redis支持数据持久化、主从复制、Lua脚本等特性,并且广泛应用于Web应用、实时计算、日志分析、消息发布等场景。
什么是Jedis Jedis是Redis官方推荐的Java连接Redis的客户端库,提供了丰富的API和易于使用的接口,使得Java开发人员能够轻松地与Redis进行交互。Jedis支持连接池、集群、管道和事务等特性,在高并发,高吞吐量的场景下,提供了性能优秀和稳定可靠的解决方案。Jedis在Redis社区得到了广泛的应用和支持,是Java开发人员使用Redis的首选客户端库之一。 以下是一个简单的使用Jedis连接Redis服务器,并执行一些Redis操作的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import redis.clients.jedis.Jedis;public class Example { public static void main (String[] args) { Jedis jedis = new Jedis ("localhost" , 6379 ); jedis.set("key1" , "value1" ); String value = jedis.get("key1" ); System.out.println(value); jedis.hset("hash1" , "field1" , "value1" ); System.out.println(jedis.hgetAll("hash1" )); jedis.close(); } }
什么是Spring Data Redis Spring Data Redis是Spring Data项目家族中的一个子项目,它通过简化和抽象操作,简化了在Redis中存储和访问数据的过程。它提供了丰富的API和基于注解的配置,使得Java开发人员能够更加便捷地与Redis交互,而无需过多地关注低级别的Redis操作。Spring Data Redis支持散列、列表、集合、有序集合等丰富的数据结构,同时也支持事务操作、消息发布订阅、Lua脚本执行、持久化等特性。通过Spring Data Redis,Java开发人员能够快速地搭建和运行分布式和高并发的应用程序。
spring-data-redis针对jedis提供了如下功能: 连接池自动管理,提供了一个高度封装的“RedisTemplate”类,提供了许多方法,包括以下几种类型的方法: 对字符串的操作方法:如opsForValue().set、opsForValue().get等方法。 对哈希的操作方法:如opsForHash().put、opsForHash().get等方法。 对列表的操作方法:如opsForList().leftPush、opsForList().rightPop等方法。 对集合的操作方法:如opsForSet().add、opsForSet().members等方法。 对有序集合的操作方法:如opsForZSet().add、opsForZSet().range等方法。 事务操作方法:如multi、watch、exec等方法。 管道操作方法:如executePipelined()方法。 异步操作方法:如opsForValue().setAsync、opsForHash().getAsync等方法。 发布订阅操作方法:如convertAndSend()方法、subscribe()方法等。 除此之外,RedisTemplate还提供了对键、连接、序列化等方面的控制和操作的方法,如delete()、getConnectionFactory()、setKeySerializer()等方法。总之,RedisTemplate提供了丰富的方法,使得Java开发者可以轻松地使用Redis。
针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为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,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。JacksonJsonRedisSerializer :jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】 RedisTemplate中API使用 首要配置 引入pom.xml依赖
1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-redis</artifactId > </dependency >
添加配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器地址 spring.redis.host=127.0 .0 .1 # Redis数据库索引(默认为0 ) spring.redis.database=0 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=-1ms # 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=5000ms
RedisTemplate的用法 首先使用@Autowired注入RedisTemplate(后面直接使用,就不特殊说明)1 2 @Autowired private RedisTemplate redisTemplate;
KEY操作 1 2 3 4 5 6 7 8 9 10 redisTemplate.delete(key); redisTemplate.delete(keys); redisTemplate.expire(key,time,TimeUnit.MINUTES); Long expire = redisTemplate.getExpire(key);redisTemplate.hasKey(key);
String类型相关操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 redisTemplate.boundValueOps("StringKey" ).set("StringValue" ); redisTemplate.boundValueOps("StringKey" ).set("StringValue" ,1 , TimeUnit.MINUTES); BoundValueOperations stringKey = redisTemplate.boundValueOps("StringKey" );stringKey.set("StringVaule" ); stringKey.set("StringValue" ,1 , TimeUnit.MINUTES); ValueOperations ops = redisTemplate.opsForValue();ops.set("StringKey" , "StringVaule" ); ops.set("StringValue" ,"StringVaule" ,1 , TimeUnit.MINUTES); redisTemplate.boundValueOps("StringKey" ).expire(1 ,TimeUnit.MINUTES); redisTemplate.expire("StringKey" ,1 ,TimeUnit.MINUTES); String str1 = (String) redisTemplate.boundValueOps("StringKey" ).get();BoundValueOperations stringKey = redisTemplate.boundValueOps("StringKey" );String str2 = (String) stringKey.get();ValueOperations ops = redisTemplate.opsForValue();String str3 = (String) ops.get("StringKey" );Boolean result = redisTemplate.delete("StringKey" );redisTemplate.boundValueOps("StringKey" ).increment(3L ); redisTemplate.boundValueOps("StringKey" ).increment(-3L );
Hash类型相关操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 redisTemplate.boundHashOps("HashKey" ).put("SmallKey" , "HashVaue" ); BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey" );hashKey.put("SmallKey" , "HashVaue" ); HashOperations hashOps = redisTemplate.opsForHash();hashOps.put("HashKey" , "SmallKey" , "HashVaue" ); redisTemplate.boundValueOps("HashKey" ).expire(1 ,TimeUnit.MINUTES); redisTemplate.expire("HashKey" ,1 ,TimeUnit.MINUTES); HashMap<String, String> hashMap = new HashMap <>(); redisTemplate.boundHashOps("HashKey" ).putAll(hashMap ); Set keys1 = redisTemplate.boundHashOps("HashKey" ).keys();BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey" );Set keys2 = hashKey.keys();HashOperations hashOps = redisTemplate.opsForHash();Set keys3 = hashOps.keys("HashKey" );List values1 = redisTemplate.boundHashOps("HashKey" ).values();BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey" );List values2 = hashKey.values();HashOperations hashOps = redisTemplate.opsForHash();List values3 = hashOps.values("HashKey" );String value1 = (String) redisTemplate.boundHashOps("HashKey" ).get("SmallKey" );BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey" );String value2 = (String) hashKey.get("SmallKey" );HashOperations hashOps = redisTemplate.opsForHash();String value3 = (String) hashOps.get("HashKey" , "SmallKey" );Map entries = redisTemplate.boundHashOps("HashKey" ).entries();BoundHashOperations hashKey = redisTemplate.boundHashOps("HashKey" );Map entries1 = hashKey.entries();HashOperations hashOps = redisTemplate.opsForHash();Map entries2 = hashOps.entries("HashKey" );redisTemplate.boundHashOps("HashKey" ).delete("SmallKey" ); redisTemplate.delete("HashKey" ); Boolean isEmpty = redisTemplate.boundHashOps("HashKey" ).hasKey("SmallKey" );
Set类型相关操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 redisTemplate.boundSetOps("setKey" ).add("setValue1" , "setValue2" , "setValue3" ); BoundSetOperations setKey = redisTemplate.boundSetOps("setKey" );setKey.add("setValue1" , "setValue2" , "setValue3" ); SetOperations setOps = redisTemplate.opsForSet();setOps.add("setKey" , "SetValue1" , "setValue2" , "setValue3" ); redisTemplate.boundValueOps("setKey" ).expire(1 ,TimeUnit.MINUTES); redisTemplate.expire("setKey" ,1 ,TimeUnit.MINUTES); Set set1 = redisTemplate.boundSetOps("setKey" ).members();BoundSetOperations setKey = redisTemplate.boundSetOps("setKey" );Set set2 = setKey.members();SetOperations setOps = redisTemplate.opsForSet();Set set3 = setOps.members("setKey" );Boolean isEmpty = redisTemplate.boundSetOps("setKey" ).isMember("setValue2" );Long size = redisTemplate.boundSetOps("setKey" ).size();Long result1 = redisTemplate.boundSetOps("setKey" ).remove("setValue1" );Boolean result2 = redisTemplate.delete("setKey" );### LIST类型相关操作 redisTemplate.boundListOps("listKey" ).leftPush("listLeftValue1" ); redisTemplate.boundListOps("listKey" ).rightPush("listRightValue2" ); BoundListOperations listKey = redisTemplate.boundListOps("listKey" );listKey.leftPush("listLeftValue3" ); listKey.rightPush("listRightValue4" ); ListOperations opsList = redisTemplate.opsForList();opsList.leftPush("listKey" , "listLeftValue5" ); opsList.rightPush("listKey" , "listRightValue6" ); ArrayList<String> list = new ArrayList <>(); redisTemplate.boundListOps("listKey" ).rightPushAll(list); redisTemplate.boundListOps("listKey" ).leftPushAll(list); redisTemplate.boundValueOps("listKey" ).expire(1 ,TimeUnit.MINUTES); redisTemplate.expire("listKey" ,1 ,TimeUnit.MINUTES); List listKey1 = redisTemplate.boundListOps("listKey" ).range(0 , 10 ); String listKey2 = (String) redisTemplate.boundListOps("listKey" ).leftPop(); String listKey3 = (String) redisTemplate.boundListOps("listKey" ).rightPop(); String listKey4 = (String) redisTemplate.boundListOps("listKey" ).index(1 );Long size = redisTemplate.boundListOps("listKey" ).size();redisTemplate.boundListOps("listKey" ).set(3L ,"listLeftValue3" ); redisTemplate.boundListOps("listKey" ).remove(3L ,"value" );
Zset类型的相关操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 redisTemplate.boundZSetOps("zSetKey" ).add("zSetVaule" , 100D ); BoundZSetOperations zSetKey = redisTemplate.boundZSetOps("zSetKey" );zSetKey.add("zSetVaule" , 100D ); ZSetOperations zSetOps = redisTemplate.opsForZSet();zSetOps.add("zSetKey" , "zSetVaule" , 100D ); DefaultTypedTuple<String> p1 = new DefaultTypedTuple <>("zSetVaule1" , 2.1D ); DefaultTypedTuple<String> p2 = new DefaultTypedTuple <>("zSetVaule2" , 3.3D ); redisTemplate.boundZSetOps("zSetKey" ).add(new HashSet <>(Arrays.asList(p1,p2))); Set<String> range = redisTemplate.boundZSetOps("zSetKey" ).range(0 , -1 ); Double score = redisTemplate.boundZSetOps("zSetKey" ).score("zSetVaule" );Long size = redisTemplate.boundZSetOps("zSetKey" ).size();Long COUNT = redisTemplate.boundZSetOps("zSetKey" ).count(0D , 2.2D );Set byScore = redisTemplate.boundZSetOps("zSetKey" ).rangeByScore(0D , 2.2D );Set<String> ranking2 = redisTemplate.opsForZSet().rangeByScore("zSetKey" , 0D , 2.2D 1 , 3 ); Set<TypedTuple<String>> tuples = redisTemplate.boundZSetOps("zSetKey" ).rangeWithScores(0L , 3L ); for (TypedTuple<String> tuple : tuples) { System.out.println(tuple.getValue() + " : " + tuple.getScore()); }ss Long startRank = redisTemplate.boundZSetOps("zSetKey" ).rank("zSetVaule" );Long endRank = redisTemplate.boundZSetOps("zSetKey" ).reverseRank("zSetVaule" );redisTemplate.boundZSetOps("zSetKey" ).remove("zSetVaule" ); redisTemplate.boundZSetOps("zSetKey" ).removeRange(0L ,3L ); redisTemplate.boundZSetOps("zSetKey" ).removeRangeByScorssse(0D ,2.2D ); Double score = redisTemplate.boundZSetOps("zSetKey" ).incrementScore("zSetVaule" ,1.1D );