详解java之redis篇(spring-data-redis整合)
1,利用spring-data-redis整合
项目使用的pom.xml:
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.x.redis</groupid> <artifactid>spring_redis</artifactid> <version>1.0-snapshot</version> <packaging>jar</packaging> <name>spring_redis</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceencoding>utf-8</project.build.sourceencoding> </properties> <dependencies> <dependency> <groupid>org.springframework.data</groupid> <artifactid>spring-data-redis</artifactid> <version>1.0.2.release</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-core</artifactid> <version>3.1.2.release</version> </dependency> <dependency> <groupid>redis.clients</groupid> <artifactid>jedis</artifactid> <version>2.1.0</version> </dependency> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.8.2</version> <scope>test</scope> </dependency> <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> <version>1.6.1</version> </dependency> <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 --> <dependency> <groupid>org.slf4j</groupid> <artifactid>jcl-over-slf4j</artifactid> <version>1.6.1</version> </dependency> <!-- hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 --> <dependency> <groupid>commons-logging</groupid> <artifactid>commons-logging</artifactid> <version>1.1.1</version> <scope>provided</scope> </dependency> <!-- slf4j的实现:logback,用来取代log4j。更快、更强! --> <dependency> <groupid>ch.qos.logback</groupid> <artifactid>logback-classic</artifactid> <version>0.9.24</version> <scope>runtime</scope> </dependency> </dependencies> </project>
除了log部分,只有一个spring core 和 spring-data-redis了
项目文件目录结构:
applicationcontext.xml:
1,context:property-placeholder 标签用来导入properties文件。从而替换${redis.maxidle}这样的变量。
2,context:component-scan 是为了在com.x.redis.dao报下的类能够实用spring的注解注入的方式。
3,事实上我们只需要把jedispoolconfig配数来就好了,接下来就是spring的封装了。所以直接看userdaoimpl的实现就明白了。
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" 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:property-placeholder location="classpath:redis.properties" /> <context:component-scan base-package="com.x.redis.dao"> </context:component-scan> <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> <bean id="connectionfactory" class="org.springframework.data.redis.connection.jedis.jedisconnectionfactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolconfig"/> <bean id="redistemplate" class="org.springframework.data.redis.core.stringredistemplate"> <property name="connectionfactory" ref="connectionfactory" /> </bean> <bean id="userdao" class="com.x.redis.dao.impl.userdaoimpl" /> </beans>
redis.properties:
# redis settings #redis.host=192.168.20.101 #redis.port=6380 #redis.pass=foobared redis.host=127.0.0.1 redis.port=6379 redis.pass= redis.maxidle=300 redis.maxactive=600 redis.maxwait=1000 redis.testonborrow=true
userdaoimpl:
1,spring对dao层的封装很多用了类似于下面代码的模板方式。
2,redistemplate就是spring对redis的一个封装而已。
public class userdaoimpl implements userdao { @autowired protected redistemplate<serializable, serializable> redistemplate; public void saveuser(final user user) { redistemplate.execute(new rediscallback<object>() { @override public object doinredis(redisconnection connection) throws dataaccessexception { connection.set(redistemplate.getstringserializer().serialize("user.uid." + user.getid()), redistemplate.getstringserializer().serialize(user.getname())); return null; } }); } @override public user getuser(final long id) { return redistemplate.execute(new rediscallback<user>() { @override public user doinredis(redisconnection connection) throws dataaccessexception { byte[] key = redistemplate.getstringserializer().serialize("user.uid." + id); if (connection.exists(key)) { byte[] value = connection.get(key); string name = redistemplate.getstringserializer().deserialize(value); user user = new user(); user.setname(name); user.setid(id); return user; } return null; } }); } }
其他:
user:
public class user { private long id; private string name; public long getid() { return id; } public void setid(long id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } }
测试代码:
public static void main(string[] args) { applicationcontext ac = new classpathxmlapplicationcontext("classpath:/applicationcontext.xml"); userdao userdao = (userdao)ac.getbean("userdao"); user user1 = new user(); user1.setid(1); user1.setname("obama"); userdao.saveuser(user1); user user2 = userdao.getuser(1); system.out.println(user2.getname()); }
2,不利用spring-data-redis整合
个人觉得这样整合灵活度更大,能够更加明了的完成任务。
pom.xml:
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.d.work</groupid> <artifactid>redis_templete</artifactid> <version>1.0-snapshot</version> <packaging>jar</packaging> <name>redis_templete</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceencoding>utf-8</project.build.sourceencoding> </properties> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupid>redis.clients</groupid> <artifactid>jedis</artifactid> <version>2.1.0</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-core</artifactid> <version>3.1.2.release</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-beans</artifactid> <version>3.1.2.release</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-context</artifactid> <version>3.1.2.release</version> </dependency> <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> <version>1.6.1</version> </dependency> <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 --> <dependency> <groupid>org.slf4j</groupid> <artifactid>jcl-over-slf4j</artifactid> <version>1.6.1</version> </dependency> <!-- hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 --> <dependency> <groupid>commons-logging</groupid> <artifactid>commons-logging</artifactid> <version>1.1.1</version> <scope>provided</scope> </dependency> <!-- slf4j的实现:logback,用来取代log4j。更快、更强! --> <dependency> <groupid>ch.qos.logback</groupid> <artifactid>logback-classic</artifactid> <version>0.9.24</version> <scope>runtime</scope> </dependency> </dependencies> </project>
目录结构:
data-source.xml
1,context:property-placeholder 和 context:component-scan 前面解释过啦。
2,配置了一个shardedjedispool,在jdeis里 还有个jedispool。这两个的区别:
一个是分片形式,可以连接有主备的redis服务端,一个是单个的。详细后续学习
3,因为不使用spring-data-redis的封装,所以自己要自己封装一个
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" 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:property-placeholder location="classpath:redis.properties" /> <context:component-scan base-package="com.d.work.main"> </context:component-scan> <context:component-scan base-package="com.d.work.redis"> </context:component-scan> <bean id="jedispoolconfig" class="redis.clients.jedis.jedispoolconfig"> <property name="maxactive" value="50" /> <property name="maxidle" value="8" /> <property name="maxwait" value="1000" /> <property name="testonborrow" value="true"/> <property name="testonreturn" value="true"/> <!-- <property name="testwhileidle" value="true"/> --> </bean> <bean id="shardedjedispool" class="redis.clients.jedis.shardedjedispool" scope="singleton"> <constructor-arg index="0" ref="jedispoolconfig" /> <constructor-arg index="1"> <list> <bean class="redis.clients.jedis.jedisshardinfo"> <constructor-arg name="host" value="${redis.host}" /> <constructor-arg name="port" value="${redis.port}" /> <constructor-arg name="timeout" value="${redis.timeout}" /> <constructor-arg name="weight" value="1" /> </bean> </list> </constructor-arg> </bean> </beans>
redisdatasource:定义三个方法
public interface redisdatasource { public abstract shardedjedis getredisclient(); public void returnresource(shardedjedis shardedjedis); public void returnresource(shardedjedis shardedjedis,boolean broken); }
实现redisdatasource:
1, 注入配置好的shardedjedispool,这三个方法的作用:
- getredisclient() : 取得redis的客户端,可以执行命令了。
- returnresource(shardedjedis shardedjedis) : 将资源返还给pool
- returnresource(shardedjedis shardedjedis, boolean broken) : 出现异常后,将资源返还给pool (其实不需要第二个方法)
@repository("redisdatasource") public class redisdatasourceimpl implements redisdatasource { private static final logger log = loggerfactory.getlogger(redisdatasourceimpl.class); @autowired private shardedjedispool shardedjedispool; public shardedjedis getredisclient() { try { shardedjedis shardjedis = shardedjedispool.getresource(); return shardjedis; } catch (exception e) { log.error("getredisclent error", e); } return null; } public void returnresource(shardedjedis shardedjedis) { shardedjedispool.returnresource(shardedjedis); } public void returnresource(shardedjedis shardedjedis, boolean broken) { if (broken) { shardedjedispool.returnbrokenresource(shardedjedis); } else { shardedjedispool.returnresource(shardedjedis); } } }
第二层的封装:redisclienttemplate,例子实现了放值和取值。最后代码提供了全部命令的实现。
代码就是映射性质的又一次调用jedis的方法而已,用了个broken来做标示符,决定返还资源的方式。
这一层的目的主要也是让再上层的调用不需要关心pool中链接的取得和返还问题了。
@repository("redisclienttemplate") public class redisclienttemplate { private static final logger log = loggerfactory.getlogger(redisclienttemplate.class); @autowired private redisdatasource redisdatasource; public void disconnect() { shardedjedis shardedjedis = redisdatasource.getredisclient(); shardedjedis.disconnect(); } /** * 设置单个值 * * @param key * @param value * @return */ public string set(string key, string value) { string result = null; shardedjedis shardedjedis = redisdatasource.getredisclient(); if (shardedjedis == null) { return result; } boolean broken = false; try { result = shardedjedis.set(key, value); } catch (exception e) { log.error(e.getmessage(), e); broken = true; } finally { redisdatasource.returnresource(shardedjedis, broken); } return result; } /** * 获取单个值 * * @param key * @return */ public string get(string key) { string result = null; shardedjedis shardedjedis = redisdatasource.getredisclient(); if (shardedjedis == null) { return result; } boolean broken = false; try { result = shardedjedis.get(key); } catch (exception e) { log.error(e.getmessage(), e); broken = true; } finally { redisdatasource.returnresource(shardedjedis, broken); } return result; } }
测试代码:
public static void main(string[] args) { applicationcontext ac = new classpathxmlapplicationcontext("classpath:/data-source.xml"); redisclienttemplate redisclient = (redisclienttemplate)ac.getbean("redisclienttemplate"); redisclient.set("a", "abc"); system.out.println(redisclient.get("a")); }
附上redisclienttemplate全部实现:
redisclienttemplate代码太多,附上下载地址:http://xiazai.jb51.net/201701/yuanma/redisclienttemplate_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Java单测void类型的方法详解