GitHub:https://github.com/asd821300801/Redis-Java-Client-Jedis/tree/spring-data-redis
Spring 集成 Redis
spring-data-redis针对jedis提供了如下功能:
- 连接池自动管理,提供了一个高度封装的“RedisTemplate”类
- 针对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)
基于设计模式,和JMS开发思路,将pub/sub的API设计进行了封装,使开发更加便捷。
spring-data-redis中,并没有对sharding提供良好的封装,如果你的架构是基于sharding,那么你需要自己去实现,这也是sdr和jedis相比,唯一缺少的特性。
前期准备
Maven加入依赖
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.5.RELEASE</version>
</dependency>
spring配置文件中加入redis相关依赖
- src/main/resources目录下创建spring配置文件:application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.lingdu.spring.redis"
annotation-config="true" />
<!-- scanner redis properties -->
<context:property-placeholder location="classpath:redis.properties" />
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}"></property>
<property name="maxIdle" value="${redis.pool.maxIdle}"></property>
<property name="minIdle" value="${redis.pool.minIdle}"></property>
<property name="maxWaitMillis" value="${redis.pool.maxTotal}"></property>
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"></property>
<property name="testOnReturn" value="${redis.pool.testOnReturn}"></property>
<property name="testWhileIdle" value="${redis.pool.testWhileIdle}"></property>
<property name="minEvictableIdleTimeMillis" value="300000"></property>
<property name="numTestsPerEvictionRun" value="3"></property>
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
destroy-method="destroy">
<property name="hostName" value="${redis.ip}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.auth}" />
<property name="timeout" value="15000" />
<property name="database" value="0" />
<property name="usePool" value="true" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
</beans>
- src/main/resources目录下创建redis配置文件:redis.properties
#最大连接数, 默认10个
redis.pool.maxTotal=10
#最小空闲连接数,默认2个
redis.pool.minIdle=2
#最大空闲连接数,默认10个
redis.pool.maxIdle=10
#最大的等待时间
redis.pool.maxWait=1000
#如果为true,表示有一个idle object evitor线程对idle object进行扫描,如果validate失败,此object会被从pool中drop掉;
#这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
redis.pool.testWhileIdle=true
#获得一个jedis实例的时候是否检查连接可用性(ping());如果为true,则得到的jedis实例均是可用的;
redis.pool.testOnBorrow=true
#return 一个jedis实例给pool时,是否检查连接可用性(ping());
redis.pool.testOnReturn=true
#host
redis.ip=127.0.0.1
#port
redis.port=6379
#auth
redis.auth=123456
- 创建spring工具类用来加载配置文件(方便测试)
SpringUtil.java
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware{
private static ApplicationContext ctx;
public static void init(String path){
ctx=new ClassPathXmlApplicationContext(path);
}
public static <T> T getBean(Class<T> type){
return ctx.getBean(type);
}
public static Object getBean(String id){
return ctx.getBean(id);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx=applicationContext;
}
}
启动redis服务器
RedisTemplate 的简单使用
RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:
1) keySerializer :对于普通K-V操作时,key采取的序列化策略
2) valueSerializer:value采取的序列化策略
3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
4) hashValueSerializer:hash-value的序列化策略
建议key/hashKey采用StringRedisSerializer。
- application.xml中注册Bean
<!-- redis template definition p表示对该bean里面的属性进行注入,格式为p:属性名=注入的对象 效果与在bean里面使用<property>标签一样 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory">
<!-- 序列化方式 建议key/hashKey采用StringRedisSerializer。 -->
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean>
- SpringRedisTemp.java
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import com.lingdu.common.util.SpringUtil;
/**
* RedisTemplate 的简单使用
* @author LingDu
*/
@SuppressWarnings("unchecked")
public class SpringRedisTemp {
private static RedisTemplate<String,Object> redisTemplate;
private static ValueOperations<String, Object> valueOper;
static{
SpringUtil.init("classpath:application.xml");
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
valueOper = redisTemplate.opsForValue();
}
//设置K-V
public void set(String key,String value){
valueOper.set(key, value);
}
//获取V
public String get(String key){
return (String) valueOper.get(key);
}
//通过K删除对应的V
public void remove(String key){
redisTemplate.delete(key);
}
public static void main(String[] args) {
SpringRedisTemp springRedisTemp = new SpringRedisTemp();
springRedisTemp.set("key", "value1");
System.out.println(springRedisTemp.get("key"));
//删除
springRedisTemp.remove("key");
System.out.println("删除之后:" + springRedisTemp.get("key"));
}
}
spring-data-redis 操作对象
- 注意:要对对象进行操作必须实现序列化接口
spring-data-redis提供了多种serializer策略,这对使用jedis的开发者而言,实在是非常便捷。
SDR提供了4种内置的serializer:
1、JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储
2、StringRedisSerializer:字符串编码,数据以string存储
3、JacksonJsonRedisSerializer:json格式存储
4、OxmSerializer:xml格式存储
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略
- ObjectToRedis.java
import java.io.Serializable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import com.lingdu.common.util.SpringUtil;
/**
* 存储对象到Redis
*
* @author LingDu
*/
@SuppressWarnings("unchecked")
public class ObjectToRedis {
private static RedisTemplate<String, Object> redisTemplate;
private static ValueOperations<String, Object> valueOper;
static {
SpringUtil.init("classpath:application.xml");
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
valueOper = redisTemplate.opsForValue();
}
// 设置K-V
public void setObject(String key, Object value) {
valueOper.set(key, value);
}
// 获取V
public String getObject(String key) {
return (String) valueOper.get(key);
}
// 通过K删除对应的V
public void removeObject(String key) {
redisTemplate.delete(key);
}
public static void main(String[] args) {
User u = new User();
u.setUserId("x101");
u.setUsername("LingDu");
u.setPassword("123456");
valueOper.set("user", u);
System.out.println(valueOper.get("user"));
ObjectToRedis objectToRedis = new ObjectToRedis();
objectToRedis.removeObject("user");
System.out.println("删除之后的对象:" + valueOper.get("user"));
}
}
/**
* 用于测试的对象,必须实现序列化接口
*
* @author LingDu
*/
class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String userId;
private String username;
private String password;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [userId=" + userId + ", username=" + username + ", password=" + password + "]";
}
}
Spring-data-redis对string操作的封装
- 在application.xml注册Bean
<!-- 对string操作的封装 -->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connection-factory-ref="jedisConnectionFactory" />
- StringRedisTemp.java
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import com.lingdu.common.util.SpringUtil;
/**
* Redis 操作 String
* @author LingDu
*/
public class StringRedisTemp {
private static StringRedisTemplate stringRedisTemplate;
private static ValueOperations<String, String> stringOFV;
static{
SpringUtil.init("classpath:application.xml");
stringRedisTemplate = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");
stringOFV = stringRedisTemplate.opsForValue();
}
public void set(String key,String value){
stringOFV.set(key, value);
}
public String get(String key){
return stringOFV.get(key);
}
public static void main(String[] args) {
StringRedisTemp stringRedisTemp = new StringRedisTemp();
stringRedisTemp.set("string_key", "string_value");
System.out.println(stringRedisTemp.get("string_key"));
}
}