Reprint: http://blog.csdn.net/xiadi934/article/details/50786293
Project environment: in SPRINGMVC +spring + MyBatis + MySQL. Redis is deployed on Linux virtual machines.
1. Overall thinking
- Reference Ehcache implements MyBatis level two cache code (MAVEN reference jar lookup)
- Using spring to manage Redis connection pooling
- Imitate Ehcachecache, realize Rediscache
2. Join Maven Dependency in Pom.xml
1 <!--Spring-redis Implementation--2 <dependency> 3 <groupId>org.springframework.data</groupId> 4 <artifactId>spring-data-redis</artifactId> 5 <version>1.6.2.RELEASE</version> 6 </dependency> 7 <!--Redis Client Jar--8 <dependency> 9 <groupid>redis.clients</groupid >10 <artifactid>jedis</artifactid>11 <version>2.8.0</version>12 </ Dependency>13 <!--Ehcache implementation for reference-->14 <dependency>15 <groupid>org.mybatis</groupid >16 <artifactid>mybatis-ehcache</artifactid>17 <version>1.0.0</version>18 </dependency>
3. Introducing Redis configuration into the Applicationcontext.xml
1 <!--introduction of database Configuration file--2 <bean id= "Propertyconfigurer" class= "Org.springframework.beans.factory.config.Propert Yplaceholderconfigurer "> 3 <property name=" Locations "> 4 <list> 5 <value>clas Spath:jdbc.properties</value> 6 <value>classpath:redis.properties</value> 7 </lis T> 8 </property> 9 </bean>10 <!--redis data source-->11 <bean id= "Poolconfig" class= "redis.clients.je Dis. Jedispoolconfig "> <property name=" maxidle "value=" ${redis.maxidle} "/> <property name=" MaxTota L "value=" ${redis.maxactive} "/> <property name=" Maxwaitmillis "value=" ${redis.maxwait} "/> Roperty name= testonborrow "value=" ${redis.testonborrow} "/> </bean>17 <!--spring-redis Connection Pool Management factory-- <bean id= "Jedisconnectionfactory" 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 "/> <!-- Use intermediate classes to resolve static injection of rediscache.jedisconnectionfactory, enabling MyBatis to implement a third-party cache-->21 <bean id= "Rediscachetransfer" class= " Com.strive.cms.cache.RedisCacheTransfer ">22 <property name=" jedisconnectionfactory "ref=" Jedisconnectionfactory "/>23 </bean>
4. Create a cache implementation class Rediscache
1/** 2 * 3 * Description: Use a third-party in-memory database Redis as a two-level cache 4 * @ Copyright: Copyright (c) 2016 5 * @ Author: xiad 6 * @ Version: 1.0 7 * @ Created Date : March 2, 2016 8 * @ Created: PM 8:02:57 9 */public class Rediscache implements Cache each {The private static final Lo Gger logger = Loggerfactory.getlogger (Rediscache.class); private static Jedisconnectionfactory jedisconnectionfactory; Private final String ID; /** * The {@code readwritelock}. * * * Private final Readwritelock Readwritelock = new Reentrantreadwritelock (); Public Rediscache (final String ID) {if (id = = NULL) {$ throw new Illegalargumentexcep tion ("Cache instances require an ID"); Logger.debug ("mybatisrediscache:id=" + ID); This.id = ID; () @Override The public void Clear () {jedisconnection connection = null; 35 Try connection {PNS = JEDISCONNECTIONFACTORY.GEtconnection (); Connection.flushdb (); Connection.flushall (); (Jedisconnectionexception e) e.printstacktrace (); 44} 4 5 finally (connection = null) {connection.close (); 49 } (57}): GetId ()-------@Override GetObject @Override (Object key)--------------= NULL; Jedi Sconnection connection = null; Try + connection = jedisconnectionfactory.getconnection (); redisserial Izer<object> serializer = new Jdkserializationredisserializer (); The result = Serializer.deserialize (Connection.get (Serializer.serialize (key))); (jedisconnectionexception e) + (); (Connection! = null) {Connection.close ( ); + +} + return result; Bayi} @Override readwritelock Getreadwritelock (). ; The GetSize () of the @Override, the public int, the 0, the jedisconnection, the C Onnection = null; 94 Try connection = Jedisconnectionfactory.getconnection (); Teger.valueof (Connection.dbsize (). toString ()); 98} jedisconnectionexception catch (e) {101 e.printstacktrace (); 102}10 3 finally104 {Connection! = null) {106 connection.close (); 107 }108}109 return result;110}111 @Override113 public void PutObject (object key, Object Value) 114 {115 jedisconnection connection = null;116 try117 {118 connection = Jedisconnectionfactor Y.getconnection (); 119 redisserializer<object> Serializer = new Jdkserializationredisserializer (); 120 Connection.set (Serializer.serialize (key), serializer.serialize (value)), 121}122 catch (Jedisconne Ctionexception e) 123 {124 e.printstacktrace ();}126 finally127 {128 if (connection! = NULL) {129 connection.close ();}131}132}133 134 @O Verride135 public Object Removeobject (object key) 136 {137 Jedisconnection connection = null;138 Ob ject result = null;139 try140 {141 connection = jedisconnectionfactory.getconnection (); 142 Redisserializer<object> serializer = new Jdkserializationredisserializer (); 143 result =connecti On.expire (Serializer.serIalize (key), 0); 144}145 catch (jedisconnectionexception e) 146 {147 E.printstacktrace ( ); 148}149 finally150 {151 if (connection! = null) {Connection.clo SE (); 153}154}155 return result;156}157 158 public static void SETJEDISCONNECTIONFAC Tory (Jedisconnectionfactory Jedisconnectionfactory) {159 rediscache.jedisconnectionfactory = JedisConnectionFactor y;160}161 162}
5, Create intermediate class Rediscachetransfer, complete the static injection of rediscache.jedisconnectionfactory
1/** 2 * 3 * Description: Static injection Intermediate Class 4 * @ Copyright: Copyrights (c) 5 * @ Author: xiad 6 * @ Version: 1.0 7 * @ Created: March 2, 2016 8 * @ Created: PM 8:02:57 9 */10 Public class Rediscachetransfer { @Autowired14 c15/>public void Setjedisconnectionfactory (Jedisconnectionfactory jedisconnectionfactory) { Rediscache.setjedisconnectionfactory (jedisconnectionfactory); }17 18}
6. configuration file Redis.properties
1 # Redis Settings 2 redis.host=192.168.25.1323 redis.port=6379 4 redis.pass=5 6 redis.maxidle=300 7 redis.maxactive=600 8 redis.maxwait=1000
7, mapper to add MyBatis two level cache
<mapper namespace= "Com.strive.cms.dao.site.CatalogMapper" > <cache type= " Com.strive.cms.cache.RedisCache "/> .....</mapper>
8. MyBatis Global Configuration
1 <?xml version= "1.0" encoding= "UTF-8"?> 2 <! DOCTYPE Configuration 3 Public "-//mybatis.org//dtd Config 3.0//en" 4 "Http://mybatis.org/dtd/mybatis-3-co Nfig.dtd "> 5 <configuration> 6 <!--configure MyBatis cache, lazy load and so on a series of properties--7 <settings> 8 9 &L t;! ---Global mapper Enable cache-->10 <setting name= "cacheenabled" value= "true"/>11 <!--query, close associated object instant load to improve performance- ->13 <setting name= "lazyloadingenabled" value= "false"/>14 <!--for unknown SQL queries, allow different result sets to be returned to achieve a common effect Fruit-->16 <setting name= "multipleresultsetsenabled" value= "true"/>17 <!--allows column labels to be used instead of column names-->1 9 <setting name= "Usecolumnlabel" value= "true"/>20 <!--does not allow the use of custom primary key values (such as the program-generated UUID 32-bit encoding as the key value), the data The table's PK generation policy will be overwritten-->22 <setting name= "Usegeneratedkeys" value= "false"/>23 <!--given nested resultmap to Field-Attribute Mappings support full,partial-->25 <setting name= "Automappingbehavior" value= "PARTIAL "/>26 <!--cache SQL for bulk update operations to improve performance Batch,simple-->28 <!--<setting name=" Defaultexecu Tortype "value=" BATCH "/>-->29 <!--database is still not responding for more than 25,000 seconds Timeout-->31 <!--<setting Name=" def Aultstatementtimeout "value=" 25000 "/>-->32 <!--allows using rowbounds on nested statements-->34 <setting name= "saferowboundsenabled" value= "false"/>35 <!--enables automatic mapping from CL Assic database column names a_column to camel case Classic Java property names Acolumn. -->37 <setting name= "Mapunderscoretocamelcase" value= "true"/>38 <!--MyBatis uses local CAC He to prevent circular references and speed up repeated nested queries. By default (session) all queries executed during a session is cached. If Localcachescope=statement The local session would be used just for STATEMENT execution, no data would be share D between, different calls to theSame sqlsession. -->41 <setting name= "Localcachescope" value= "SESSION"/>42 <!--Specifies the JDBC type for Null values when no specific JDBC type is provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values-like NULL, VARCHAR or other. -->45 <setting name= "Jdbctypefornull" value= "other"/>46 <!--specifies which Object ' s Metho DS trigger a lazy load-->48 <setting name= "Lazyloadtriggermethods" value= "equals,clone,hashcode,tostring"/& gt;49 <!--Sets the form of the associated object load, where the field is loaded on demand (the Load field is specified by SQL), and all fields of the associated table are not loaded to improve performance-->51 <setting name= "Aggressi Velazyloading "value=" true "/>52 </settings>54 </configuration>
9. Print SQL log for easy testing
1 #定义LOG输出级别为INFO 2 Log4j.rootlogger=info,console,file 3 4 # # #定义日志输出目的地为控制台 5 log4j.appender.console= Org.apache.log4j.ConsoleAppender 6 Log4j.appender.console.target=system.out 7 #可以灵活地指定日志输出格式, the following line specifies the specific format 8 Log4j.appender.Console.layout = Org.apache.log4j.PatternLayout 9 log4j.appender.console.layout.conversionpattern=[ %c]-%m%n10 # # # #文件大小到达指定尺寸的时候产生一个新的文件12 log4j.appender.File = Org.apache.log4j.RollingFileAppender13 #指定输出目录14 Log4j.appender.File.File = logs/ssm.log15 #定义文件最大大小16 log4j.appender.File.MaxFileSize = 10mb17 #输出所以日志, If switching to debug indicates output debug above level log Log4j.appender.File.Threshold = ALL19 Log4j.appender.File.layout = org.apache.log4j.PatternLayout20 Log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-mm-dd hh\:mm\:ss}][%c ]%M%N21 # # # # #显示本项目SQL语句部分23 Log4j.logger.com.strive.cms=debug
10. Test code
1 @RunWith (Springjunit4classrunner.class) 2 @ContextConfiguration (locations = {"Classpath:applicationContext.xml"}) 3 public class Mybatiscachesecondtest 4 {5 private static final Logger Logger = Loggerfactory.getlogger (mybatisc Achesecondtest.class); 6 7 @Autowired 8 private Siteservice service; 9 /*11 * Two-level cache test */13 @Test14 Public void TestCache2 () { pageinfo<site> Page1 = Service.querysite ("", 1, 2, "", ""); Logger.info (Page1.getlist (). Get (1). GetName ()); pageinfo<site> Page2 = Service.querysite ("", 2, 2, "", ""); Logger.info (Page2.getlist (). Get (0). GetName ()); pageinfo<site> page3 = Service.querysite ("", 1, 2, "", ""); Logger.info (Page3.getlist (). Get (0). GetName ()); 24 25}
First Run results
Subsequent run results
Query with the same conditions can be found, no longer query MySQL, but directly take Redis data
View Redis Database keys *, you will find a lot more data, the results are as follows
At this point, the Redis basic configuration succeeds.
Springmvc +spring + MyBatis + Mysql + Redis (AS Level two cache) configuration