1,利用spring-data-redis整合
项目使用的pom.xml:
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
64
65
66
67
68
|
< 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的实现就明白了。
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
|
<? 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:
1
2
3
4
5
6
7
8
9
10
11
12
|
# 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的一个封装而已。
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
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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; } } |
测试代码:
1
2
3
4
5
6
7
8
9
10
|
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:
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
64
65
66
67
68
69
70
|
< 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的封装,所以自己要自己封装一个
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
|
<? 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:定义三个方法
1
2
3
4
5
|
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 (其实不需要第二个方法)
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
|
@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中链接的取得和返还问题了。
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
64
65
|
@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; } } |
测试代码:
1
2
3
4
5
6
|
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代码太多,附上下载地址:RedisClientTemplate.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/tankaixiong/p/3660075.html