ssm框架之前已经搭建过了,这里不再做代码复制工作。
这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷新已有缓存,如果不存在就会新建缓存,所有的insert,update操作都会更新缓存。
redis的好处也显而易见,可以使系统的数据访问性能更高。本节只是展示了整合方法和效果,后面会补齐redis集群、负载均衡和session共享的文章。
下面就开始整合工作:
后台首先启动redis-server(后台启动与远程连接linux服务的方法都需要改redis.conf文件),启动命令“./src/redis-server ./redis.conf”
我这里是windows系统下开发的,推荐一个可视化工具“redis desktop manager”,需要远程连接linux下的redis,需要linux下开启端口对外开放(具体方法是修改/etc/sysconfig/iptables文件,增加对外端口开发命令)。
以上操作都完成后,即可远程连接成功了,如图:
现在还没有缓存记录,下面进入代码阶段,首先在pom.xml中增加需要的redis jar包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<dependency> <groupid>redis.clients</groupid> <artifactid>jedis</artifactid> <version> 2.9 . 0 </version> </dependency> <dependency> <groupid>org.springframework.data</groupid> <artifactid>spring-data-redis</artifactid> <version> 1.6 . 2 .release</version> </dependency> <dependency> <groupid>org.mybatis</groupid> <artifactid>mybatis-ehcache</artifactid> <version> 1.0 . 0 </version> </dependency> <!-- 添加druid连接池包 --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version> 1.0 . 24 </version> </dependency> |
pom.xml写好后,还需要新增两个配置文件:redis.properties
1
2
3
4
5
6
7
|
redis.host= 192.168 . 0.109 redis.port= 6379 redis.pass= 123456 redis.maxidle= 200 redis.maxactive= 1024 redis.maxwait= 10000 redis.testonborrow= true |
其中字段也都很好理解,再加入配置文件:spring-redis.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
|
<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:mvc= "http://www.springframework.org/schema/mvc" xmlns:util= "http://www.springframework.org/schema/util" xmlns:aop= "http://www.springframework.org/schema/aop" xmlns:context= "http://www.springframework.org/schema/context" xmlns:task= "http://www.springframework.org/schema/task" xsi:schemalocation="http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans-4.3.xsd http: //www.springframework.org/schema/util http: //www.springframework.org/schema/util/spring-util-4.3.xsd http: //www.springframework.org/schema/mvc http: //www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http: //www.springframework.org/schema/aop http: //www.springframework.org/schema/aop/spring-aop-4.3.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 连接池基本参数配置,类似数据库连接池 --> <context:property-placeholder location= "classpath*:redis.properties" /> <bean id= "poolconfig" class = "redis.clients.jedis.jedispoolconfig" > <property name= "maxtotal" value= "${redis.maxactive}" /> <property name= "maxidle" value= "${redis.maxidle}" /> <property name= "testonborrow" value= "${redis.testonborrow}" /> </bean> <!-- 连接池配置,类似数据库连接池 --> <bean id= "jedisconnectionfactory" class = "org.springframework.data.redis.connection.jedis.jedisconnectionfactory" > <property name= "hostname" value= "${redis.host}" ></property> <property name= "port" value= "${redis.port}" ></property> <property name= "password" value= "${redis.pass}" ></property> <property name= "poolconfig" ref= "poolconfig" ></property> </bean> <!-- 调用连接池工厂配置 --> <!-- <bean id= "redistemplate" class = " org.springframework.data.redis.core.redistemplate" > <property name= "jedisconnectionfactory" ref= "jedisconnectionfactory" ></property> 如果不配置serializer,那么存储的时候智能使用string,如果用user类型存储,那么会提示错误user can't cast to string!!! <property name= "keyserializer" > <bean class = "org.springframework.data.redis.serializer.stringredisserializer" /> </property> <property name= "valueserializer" > <bean class = "org.springframework.data.redis.serializer.jdkserializationredisserializer" /> </property> </bean> --> <bean id= "rediscachetransfer" class = "com.cjl.util.rediscachetransfer" > <property name= "jedisconnectionfactory" ref= "jedisconnectionfactory" /> </bean> </beans> |
配置文件写好后,就开始java代码的编写:
jedisclusterfactory.java
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
71
72
73
|
package com.cjl.util; import java.util.hashset; import java.util.properties; import java.util.set; import java.util.regex.pattern; import org.apache.commons.pool2.impl.genericobjectpoolconfig; import org.springframework.beans.factory.factorybean; import org.springframework.beans.factory.initializingbean; import org.springframework.core.io.resource; import redis.clients.jedis.hostandport; import redis.clients.jedis.jediscluster; public class jedisclusterfactory implements factorybean<jediscluster>, initializingbean { private resource addressconfig; private string addresskeyprefix; private jediscluster jediscluster; private integer timeout; private integer maxredirections; private genericobjectpoolconfig genericobjectpoolconfig; private pattern p = pattern.compile( "^.+[:]\\d{1,5}\\s*$" ); public jediscluster getobject() throws exception { return jediscluster; } public class <? extends jediscluster> getobjecttype() { return ( this .jediscluster != null ? this .jediscluster.getclass() : jediscluster. class ); } public boolean issingleton() { return true ; } private set<hostandport> parsehostandport() throws exception { try { properties prop = new properties(); prop.load( this .addressconfig.getinputstream()); set<hostandport> haps = new hashset<hostandport>(); for (object key : prop.keyset()) { if (!((string) key).startswith(addresskeyprefix)) { continue ; } string val = (string) prop.get(key); boolean isipport = p.matcher(val).matches(); if (!isipport) { throw new illegalargumentexception( "ip 或 port 不合法" ); } string[] ipandport = val.split( ":" ); hostandport hap = new hostandport(ipandport[ 0 ], integer.parseint(ipandport[ 1 ])); haps.add(hap); } return haps; } catch (illegalargumentexception ex) { throw ex; } catch (exception ex) { throw new exception( "解析 jedis 配置文件失败" , ex); } } public void afterpropertiesset() throws exception { set<hostandport> haps = this .parsehostandport(); jediscluster = new jediscluster(haps, timeout, maxredirections, genericobjectpoolconfig); } public void setaddressconfig(resource addressconfig) { this .addressconfig = addressconfig; } public void settimeout( int timeout) { this .timeout = timeout; } public void setmaxredirections( int maxredirections) { this .maxredirections = maxredirections; } public void setaddresskeyprefix(string addresskeyprefix) { this .addresskeyprefix = addresskeyprefix; } public void setgenericobjectpoolconfig(genericobjectpoolconfig genericobjectpoolconfig) { this .genericobjectpoolconfig = genericobjectpoolconfig; } } |
rediscache.java
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
package com.cjl.util; import java.util.concurrent.locks.readwritelock; import java.util.concurrent.locks.reentrantreadwritelock; import org.apache.ibatis.cache.cache; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.data.redis.connection.jedis.jedisconnection; import org.springframework.data.redis.connection.jedis.jedisconnectionfactory; import org.springframework.data.redis.serializer.jdkserializationredisserializer; import org.springframework.data.redis.serializer.redisserializer; import redis.clients.jedis.exceptions.jedisconnectionexception; public class rediscache implements cache { private static final logger logger = loggerfactory.getlogger(rediscache. class ); private static jedisconnectionfactory jedisconnectionfactory; private final string id; private final readwritelock rwl = new reentrantreadwritelock(); public rediscache( final string id) { if (id == null ) { throw new illegalargumentexception( "cache instances require an id" ); } logger.debug( "mybatisrediscache:id=" + id); this .id = id; } /** * 清空所有缓存 */ public void clear() { rwl.readlock().lock(); jedisconnection connection = null ; try { connection = jedisconnectionfactory.getconnection(); connection.flushdb(); connection.flushall(); } catch (jedisconnectionexception e) { e.printstacktrace(); } finally { if (connection != null ) { connection.close(); } rwl.readlock().unlock(); } } public string getid() { return this .id; } /** * 获取缓存总数量 */ public int getsize() { int result = 0 ; jedisconnection connection = null ; try { connection = jedisconnectionfactory.getconnection(); result = integer.valueof(connection.dbsize().tostring()); logger.info( "添加mybaits二级缓存数量:" + result); } catch (jedisconnectionexception e) { e.printstacktrace(); } finally { if (connection != null ) { connection.close(); } } return result; } public void putobject(object key, object value) { rwl.writelock().lock(); jedisconnection connection = null ; try { connection = jedisconnectionfactory.getconnection(); redisserializer<object> serializer = new jdkserializationredisserializer(); connection.set(serializeutil.serialize(key), serializeutil.serialize(value)); logger.info( "添加mybaits二级缓存key=" + key + ",value=" + value); } catch (jedisconnectionexception e) { e.printstacktrace(); } finally { if (connection != null ) { connection.close(); } rwl.writelock().unlock(); } } public object getobject(object key) { // 先从缓存中去取数据,先加上读锁 rwl.readlock().lock(); object result = null ; jedisconnection connection = null ; try { connection = jedisconnectionfactory.getconnection(); redisserializer<object> serializer = new jdkserializationredisserializer(); result = serializer.deserialize(connection.get(serializer.serialize(key))); logger.info( "命中mybaits二级缓存,value=" + result); } catch (jedisconnectionexception e) { e.printstacktrace(); } finally { if (connection != null ) { connection.close(); } rwl.readlock().unlock(); } return result; } public object removeobject(object key) { rwl.writelock().lock(); jedisconnection connection = null ; object result = null ; try { connection = jedisconnectionfactory.getconnection(); redisserializer<object> serializer = new jdkserializationredisserializer(); result = connection.expire(serializer.serialize(key), 0 ); } catch (jedisconnectionexception e) { e.printstacktrace(); } finally { if (connection != null ) { connection.close(); } rwl.writelock().unlock(); } return result; } public static void setjedisconnectionfactory(jedisconnectionfactory jedisconnectionfactory) { rediscache.jedisconnectionfactory = jedisconnectionfactory; } public readwritelock getreadwritelock() { // todo auto-generated method stub return rwl; } } |
rediscachetransfer.java
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.cjl.util; import org.springframework.beans.factory.annotation.autowired; import org.springframework.data.redis.connection.jedis.jedisconnectionfactory; /** * 静态注入中间类 */ public class rediscachetransfer { @autowired public void setjedisconnectionfactory(jedisconnectionfactory jedisconnectionfactory) { rediscache.setjedisconnectionfactory(jedisconnectionfactory); } } |
serializeutil.java
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
|
package com.cjl.util; import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.objectinputstream; import java.io.objectoutputstream; /** * * @author cjl * */ public class serializeutil { /** * 序列化 */ public static byte [] serialize(object object) { objectoutputstream oos = null ; bytearrayoutputstream baos = null ; try { // 序列化 baos = new bytearrayoutputstream(); oos = new objectoutputstream(baos); oos.writeobject(object); byte [] bytes = baos.tobytearray(); return bytes; } catch (exception e) { e.printstacktrace(); } return null ; } /** *反序列化 */ public static object unserialize( byte [] bytes) { if (bytes != null ) { bytearrayinputstream bais = null ; try { // 反序列化 bais = new bytearrayinputstream(bytes); objectinputstream ois = new objectinputstream(bais); return ois.readobject(); } catch (exception e) { } } return null ; } } |
所有东西准备齐全后还需要修改映射文件
要使mybaits缓存生效,还需如上图这样开启二级缓存。配置文件还需要在web.xml中加载生效
一切准备就绪后,启动服务
启动成功后,点击员工表单可以触发查询所有员工的方法,第一次进行查询语句可以看到mybatis打印了查询语句,并在redis服务器中更新了一条缓存
我们清空控制台再次点击查询员工按钮执行查询方法,可以看到没有执行查询语句,证明第二次查询直接从缓存中取值,没有连接mysql进行查询。
总结
以上所述是小编给大家介绍的redis与ssm整合方法(mybatis二级缓存),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/cuijiale/p/8012008.html