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