一:spring-data-redis简介
spring-data-redis(以下简称SDR),是在jedis的基础之上,Spring继续进行了封装,SDR的依赖比较恶心,是基于Spring3.X的,查阅资料得知,需要如下的maven依赖。本人没有一个个尝试,在此仅作学习记录,原文请参考:
http://hello-nick-xu.iteye.com/blog/2078547
jedis在Spring中使用学习文档:
http://snowolf.iteye.com/blog/1633196
1.Spring核心包
spring-core-3.2.3.RELEASE.jar
spring-beans-3.2.3.RELEASE.jar
spring-context-3.2.3.RELEASE.jar
spring-context-support-3.2.3.RELEASE.jar
spring-expression-3.2.3.RELEASE.jar
spring-tx-3.2.3.RELEASE.jar
spring-aop-3.2.3.RELEASE.jar
commons-logging.jar
log4j-1.2.15.jar
jedis-2.1.0.jar
commons-pool.jar
4.SDR依赖
spring-data-redis-1.0.0.RELEASE.jar
下图反应了大体的关系:
二:需要的maven
<!-- redis核心包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
核心,一个spring-data-redis,一个jedis的jar。
三:Spring中配置和调用类
redis.properties
# Redis settings
redis.host =localhost
redis.port =6379
redis.maxIdle =300
redis.default.db =0
redis.timeout =100000
redis.maxActive =600
redis.maxWait =1000
redis.testOnBorrow =true
本地地址,端口,最大连接数,默认DB数,等待超时时间,testOnBorrow:这个是指jedis取连接池时候,若连接无效或关闭,取下一个连接,避免同一个连接而错误
spring-redis.xml
<!-- 引入多个配置文件 -->
<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:conf/spring/jdbc.properties</value>
<value>classpath:conf/spring/log4j.properties</value>
<value>classpath:conf/spring/redis.properties</value>
</list>
</property>
</bean>
<!-- jedis pool配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxActive" value="${redis.maxActive}" />
<property name="maxWait" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- spring data redis -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true" />
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<!-- <property name="password" value="${redis.pass}" /> -->
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.db}" />
<constructor-arg index="0" ref="poolConfig" />
</bean>
<!-- redis模板类 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!-- redisService 实现类 -->
<bean id="redisService" class="com.redis.service.RedisService ">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:conf/spring/jdbc.properties</value>
<value>classpath:conf/spring/log4j.properties</value>
<value>classpath:conf/spring/redis.properties</value>
</list>
</property>
</bean>
表示Spring加载properties配置文件。
画外音:之前我引入配置文件使用的时候是如下方式:
<context:property-placeholder location="classpath:conf/spring/redis.properties" />
当只是在一个XML文件中还好,如果多个XML文件中这样子引配置文件,然后再${}的方式去引用参数,就会报参数错误,个人认为是因为Spring是用
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
进行统计管理的,不同的XML中 以placeHode的形势引入会把Spring创建的默认的这些Bean进行了覆盖,所以有个技巧就是所有的properties文件,统一以list形式引入。
<!-- jedis pool配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxActive" value="${redis.maxActive}" />
<property name="maxWait" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
jedis连接池,这里貌似使用了一种设计模式,池-工厂-模板,不懂,不过Spring好像很多都是这样配置的,待学习设计模式!
<!-- spring data redis -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true" />
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<!-- <property name="password" value="${redis.pass}" /> -->
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.db}" />
<constructor-arg index="0" ref="poolConfig" />
</bean>
连接工厂,从jedis池子中取redis连接的实例对象,我这里redis没密码。
<!-- redis模板类 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
redis模板类,Spring-data-redis包提供。
<!-- redisService 实现类 -->
<bean id="redisService" class="com.redis.service.RedisService ">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
set方式注入我们自己写的类,redisService。指明成员,redisTemplate。
自己定义一个pojo,如下:
Student.java
package com.test.dao;
import java.io.Serializable;
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
private String id;
private String name;
private int money;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
没什么可说的。
RedisService.java
package com.redis.service;
import java.io.Serializable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import com.test.dao.Student;
/**
* redis读写数据Demo,注意要点
* 1.jsp到redis 需要序列化 redisTemplate.getStringSerializer().serialize(XXXXX)
* 2.redis数据读出来,需要反序列化,才能保证中文等不乱码 redisTemplate.getStringSerializer().deserialize(XXXXX)
* @author Sww
*
*/
public class RedisService{
private RedisTemplate<Serializable, Serializable> redisTemplate;
public void setRedisTemplate(
RedisTemplate<Serializable, Serializable> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 新增学生ID,姓名
* @param student
* @return
*/
public void save(final Student student) {
redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
connection.set(
//请注意加前缀表示命名空间 例如student.uid
redisTemplate.getStringSerializer().serialize(
"student.uid:" + student.getId()),
//需要序列化操作
redisTemplate.getStringSerializer().serialize(
student.getName())
);
return null;
}
});
}
/**
* 根据ID查询学生姓名
* @param id
* @return
*/
public Student select(final String id){
return redisTemplate.execute(new RedisCallback<Student>() {
public Student doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] key = redisTemplate.getStringSerializer().serialize(
"student.uid:" + id);
if (connection.exists(key)) {
byte[] value = connection.get(key);
//从redis中取出的需要反序列化--- deserialize
String name = redisTemplate.getStringSerializer()
.deserialize(value);
Student student = new Student();
student.setId(id);
student.setName(name);
return student;
}
return null;
}
});
}
/**
* 根据学生ID删除学生信息
* @param id
*/
public void delete(final String id){
redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection)
throws DataAccessException {
connection.del(redisTemplate.getStringSerializer().serialize(
"student.uid:" + id));
return null;
}
});
}
}
如上的写法,我也是在模仿中,不熟,这是一种内部类的写法吧,又是设计模式
,亟待学习这方面啊。要点:
1.加前缀,表示简单的区分,防止不同空间相同的key覆盖。
2.jsp到redis 需要序列化 redisTemplate.getStringSerializer().serialize(XXXXX),这样子中文写在redis中不会乱码
2.jsp到redis 需要序列化 redisTemplate.getStringSerializer().serialize(XXXXX),这样子中文写在redis中不会乱码
3.redis数据读出来,需要反序列化,才能保证中文等不乱码 redisTemplate.getStringSerializer().deserialize(XXXXX)
4.进行查操作前,最好判断下key是否存在,提高查询效率。
5.其实connection.set也就是放一对键值对到redis中。connection.get(key)则是根据key取出value值。而connection.get(key)则是直接根据key值删除。
四:测试
RedisMain.java
package com.test.controller.main;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.redis.service.RedisService;
import com.test.dao.Student;
/**
* redis 测试类
* @author Sww
*
*/
public class RedisMain {
/**
* @param args
*/
public static void main(String[] args) {
//1.获取RedisService实例对象
BeanFactory factory = new ClassPathXmlApplicationContext("classpath:conf/spring/spring-redis.xml");
RedisService test = (RedisService) factory.getBean("redisService");
Student student = new Student();
//2.新增操作
student.setId("302");
student.setName("302value");
test.save(student);
//3.查询新增
String name = test.select("302").getName();
System.out.println("id:302对应的学生名:" + name);
//4.删除新增
//test.delete("302");
System.out.println("-----------执行结束-------------");
}
}
因为删除就没有了,我把delete那一行注释掉了。望知晓。
redis上结果: