一. 为什么使用Spring-Data-Redis
Spring Framework是领先的全套Java/JEE应用程序框架。它通过使用依赖注入,AOP和便携式服务抽象来提供轻量级的容器和非侵入式编程模型。
NoSQL存储器提供了用于水平可扩展性和速度的经典RDBMS的替代方案。在实现方面,KeyValue存储是NoSQL空间中最大(最老)的成员之一。
Spring-Data-Redis框架可以轻松地通过Spring的基础架构支持,消除使用Redis键值存储的Spring应用程序,从而减少与存储库进行交互所需的冗余代码。
二. 如何使用Spring-Data-Redis
1. 引入jar包
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>1.12.4.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.0.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-keyvalue</artifactId> <version>1.1.4.RELEASE</version> <scope>provided</scope> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> <scope>provided</scope> </dependency> 2. |
其它所需要的jar包可以自行添加,spring-data-redis在1.7之前是不支持Redis集群的,所以这里采用的是1.8.0版本。
2.配置Redis连接Properties文件
在classpath下创建redis.properties文件,配置redis的连接信息,连接Redis采用的是JedisPool。
#集群的IP地址以及端口号 redis.host1=192.168.22.251 redis.port1=6380 redis.host2=192.168.22.251 redis.port2=6381 redis.host3=192.168.22.251 redis.port3=6382 redis.host4=192.168.22.251 redis.port4=6383 redis.host5=192.168.22.251 redis.port5=6384 redis.host6=192.168.22.251 redis.port6=6385 #JedisPool连接信息,可根据实际情况修改,添加,或删除 redis.minIdle=0 redis.maxIdle=8 redis.maxActive=1 redis.maxWait=1 redis.testOnBorrow=false |
3. 配置Spring配置文件
在Spring的配置文件中配置JedisPoolConfig、JedisConnectionFactory、RedisClusterConfiguration、RedisTemplate。
<?xml version="1.0" encoding="UTF-8"?>
|
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="minIdle" value="${redis.minIdle}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> |
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <!--配置集群--> <constructor-arg name="clusterConfig" ref="redisClusterConfig" /> <property name="usePool" value="true" /> <property name="poolConfig" ref="poolConfig" /> </bean> |
<bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration"> <property name="maxRedirects" value="3" /> <property name="clusterNodes"> <set> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host1}"></constructor-arg> <constructor-arg name="port" value="${redis.port1}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host2}"></constructor-arg> <constructor-arg name="port" value="${redis.port2}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host3}"></constructor-arg> <constructor-arg name="port" value="${redis.port3}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host4}"></constructor-arg> <constructor-arg name="port" value="${redis.port4}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host5}"></constructor-arg> <constructor-arg name="port" value="${redis.port5}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.host6}"></constructor-arg> <constructor-arg name="port" value="${redis.port6}"></constructor-arg> </bean> </set> </property> </bean> |
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> </property> </bean> |
4、配置spring-context.xml配置文件
<bean class="com.dmsdbj.itoo.tool.spring.SpringContextHolder" lazy-init="false" /> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="1" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:db.properties</value> <value>classpath:dubbo-server.properties</value> <value>classpath:redis.properties</value> </list> </property> </bean> <import resource="classpath:spring/dubbo.xml" /> <import resource="classpath:spring/datasource.xml" /> <import resource="classpath:spring/spring-mybatis.xml" /> <import resource="classpath:spring/spring-redis.xml" /> </beans> |
4. 使用RedisTemplate操作Redis数据库
在需要做缓存的Service类中添加RedisTemplate的注解:
@Autowired private RedisTemplate redisTemplate; |
使用时,RedisTemplate对应Redis不同数据类型有不同的操作,以及不同的key值绑定操作,详细内容看下面代码:
public void findAll() { // -----------------String类型数据操作 start-------------------- ValueOperations<String, String> stringOperations = redisTemplate .opsForValue(); // String类型数据存储,不设置过期时间,永久性保存 stringOperations.set("string1", "fiala"); // String类型数据存储,设置过期时间为80秒,采用TimeUnit控制时间单位 stringOperations.set("string2", "fiala", 80, TimeUnit.SECONDS); // 判断key值是否存在,存在则不存储,不存在则存储 stringOperations.setIfAbsent("string1", "my fiala"); stringOperations.setIfAbsent("string3", "my fiala"); String value1 = stringOperations.get("string1"); String value2 = stringOperations.get("string3"); System.out.println(value1); System.out.println(value2); // -----------------String类型数据操作 end--------------------
// -----------------其他值类型数据操作 start-------------------- Demo demo = new Demo(); demo.setId("1"); demo.setName("fiala"); List<Demo> demos = new ArrayList<Demo>(); ValueOperations<String, Object> valueOperations = redisTemplate .opsForValue(); // 设置value为对象类型,且不设置过期时间,默认永久 valueOperations.set("value1", demo); // 设置value为对象类型,设置过期时间为80秒,时间单位由TimeUnit控制 valueOperations.set("value2", demos, 80, TimeUnit.SECONDS); Demo demo1 = (Demo) valueOperations.get("value1"); System.out.println(demo1.toString()); // -----------------其他值类型数据操作 end--------------------
// -----------------List数据类型操作 start------------------ ListOperations<String, Object> listOperations = redisTemplate .opsForList(); for (int i = 0; i < 5; i++) { Demo listDemo = new Demo(); listDemo.setId("\"" + i + "\""); listDemo.setName("fiala" + i); listOperations.leftPush("list1", listDemo); listOperations.rightPush("list2", listDemo); } BoundListOperations<String, Object> boundListOperations = redisTemplate .boundListOps("list3"); for (int i = 0; i < 5; i++) { Demo listDemo = new Demo(); listDemo.setId("\"" + i + "\""); listDemo.setName("fiala" + i); boundListOperations.leftPush(listDemo); boundListOperations.rightPush(listDemo); }
System.out.println(boundListOperations.rightPop()); System.out.println(boundListOperations.leftPop());
// 可给数据排序 Demo demo2 = (Demo) listOperations.leftPop("list1"); Demo demo3 = (Demo) listOperations.rightPop("list2"); System.out.println(demo2.toString()); System.out.println(demo3.toString()); // -----------------List数据类型操作 end------------------
// -----------------set数据类型操作 start------------------ SetOperations<String, Object> setOperations = redisTemplate.opsForSet(); for (int i = 0; i < 5; i++) { Demo setDemo = new Demo(); setDemo.setId("\"" + i + "\""); setDemo.setName("fiala" + i); setOperations.add("set1", setDemo); } Demo demo4 = (Demo) setOperations.pop("set1"); System.out.println(demo4.toString()); // -----------------set数据类型操作 end------------------
// -----------------zset数据类型操作 start------------------ ZSetOperations<String, Object> zSetOperations = redisTemplate .opsForZSet(); zSetOperations.add("zset", "fiala", 0); zSetOperations.add("zset", "my fiala", 1); System.out.println(zSetOperations.rangeByScore("zset", 0, 1)); // -----------------zset数据类型操作 end------------------
// -----------------hash数据类型操作 start------------------ HashOperations<String, Object, Object> hashOperations = redisTemplate .opsForHash(); Map<String, String> map = new HashMap<String, String>(); map.put("map1", "fiala1"); map.put("map2", "fiala2"); hashOperations.putAll("hash", map); System.out.println(hashOperations.entries("hash")); // -----------------hash数据类型操作 start------------------ } |
三. 总结
Spring-Data-Redis是Spring系列框架中的一种,用于操作Redis缓存数据,与SpringFramework结合比较容易。它连接Redis是可以基于Jedis,也可以基于Lettuce,该文档是基于Jedis连接配置的。
Jedis操作Redis,需要封装一个JedisClient,否则每次都要创建Jedis,然后建立连接。RedisTemplate相当于一层封装,只要在代码中注入RedisTemplate,不需要创建Jedis即可直接操作,而且是线程安全的。