In MyBatis, developers are allowed to customize their own caches, and this article uses Redis as a level two cache for MyBatis. Defining a Level Two cache in MyBatis requires the following configuration:
1, mybatis support the total switch of level two cache: Global configuration variable parameter "Cacheenabled=true"
2. The mapper of the SELECT statement should be configured with <cache> or <cached-ref> node
3. Parameter usecache=true of SELECT statement
The MyBatis configuration file is as follows:
<settings><!--This configuration enables the global mapper to enable or disable the cache-- <setting name= "cacheenabled" value= "true"/> <!- -For unknown SQL queries, allow different result sets to be returned to achieve a common effect-- <setting name= "multipleresultsetsenabled" value= "true"/> < !--Configure the default executor. Simple actuators are nothing special. The reuse executor uses the preprocessing statement. Batch Executor uses statements and bulk updates --<setting name= "Defaultexecutortype" value= "Reuse"/> <!--globally enables or disables lazy loading. When disabled, all associated objects are loaded immediately. -- <setting name= "lazyloadingenabled" value= "false"/> <setting name= "Aggressivelazyloading" Value= "true"/> <!--<setting name= "enhancementenabled" value= "true"/> -<!--set the time-out period, It determines the time that the driver waits for a database response. -- <setting name= "defaultstatementtimeout" value= "25000"/></settings>
The configuration file for the MyBatis mapper is as follows:
<?xml version= "1.0" encoding= "UTF-8"? ><! DOCTYPE Mapper Public "-//mybatis.org//dtd mapper 3.0//en" "Http://mybatis.org/dtd/mybatis-3-mapper.dtd" >< Mapper namespace= "user" ><!--level two cache--><cache type= "Com.qunar.mobile.mybatis.cache.QRedisCache"/>< Select Id= "Getusers" resulttype= "User" usecache= "true" >select user_id as userId, user_name as username, user_ Desc as Userdesc, create_time as Createtimefrom bisystem_user</select></mapper>
A custom Level two cache requires the implementation of the MyBatis cache interface, which is implemented as follows:
public class Qrediscache implements Cache {private String cacheid;private final readwritelock readwritelock = new Reentran Treadwritelock (TRUE); Public Qrediscache (String CacheID) {if (CacheID = = null) {throw new IllegalArgumentException ("Cache instances require an I D ");} This.cacheid = CacheID;} @Overridepublic String getId () {return cacheid;} @Overridepublic void PutObject (Object key, Object value) {Jedisutils.put (key, value);} @Overridepublic object GetObject (object key) {return jedisutils.get (key);} @Overridepublic object Removeobject (object key) {return jedisutils.remove (key);} @Overridepublic void Clear () {Jedisutils.removeall ();} @Overridepublic int GetSize () {return 0;} @Overridepublic Readwritelock Getreadwritelock () {return readwritelock;}}
The auxiliary classes used in Qrediscache Jedisutils and Serializeutils are implemented as follows:
public class Jedisutils {private static final Logger Logger = Logger.getlogger (jedisutils.class);p rivate static Jedispool Jedispool;static {Properties props = new Properties (); try {props.load (JedisUtils.class.getResourceAsStream ("/ Redis.properties ")); Jedispoolconfig conf = new Jedispoolconfig () Conf.setmaxidle (integer.valueof (Props.getproperty ("Jedis.pool.maxIdle") "))); Conf.settestonborrow (Boolean.valueof (Props.getproperty ("Jedis.pool.testOnBorrow")); Conf.settestonreturn (Boolean.valueof (Props.getproperty ("Jedis.pool.testOnReturn")); Jedispool = new Jedispool (conf, Props.getproperty ("Redis.ip"), Integer.valueof (Props.getproperty ("Redis.port")); } catch (IOException e) {logger.error ("load [jedis.properties] exception [" + E.getmessage () + "]", E);}} public static Jedis Getjedis () {return Jedispool.getresource ();} public static void Recyclejedis (Jedis Jedis) {jedis.close ();} /** * Redis Storage Object Serialization stream * */public static void put (object key, Object value) {Jedis Jedis = Getjedis (); Jedis.set (seriaLizeutils.serialize (Key), serializeutils.serialize (value)); Recyclejedis (Jedis);} public static <T> T get (Object key) {Jedis Jedis = Getjedis (); T value = Serializeutils.unserialize (Jedis.get (Serializeutils.serialize (key)); Recyclejedis (Jedis); return value;} public static Long Remove (Object key) {Jedis Jedis = Getjedis (); Long num = Jedis.del (serializeutils.serialize (key)); Recyclejedis (Jedis); return num;} public static void RemoveAll () {Jedis Jedis = Getjedis (); Jedis.flushdb (); Recyclejedis (Jedis);}} public class Serializeutils {private static final Logger Logger = Logger.getlogger (serializeutils.class);p rivate Static V OID Close (ObjectOutputStream objectoutputstream, Bytearrayoutputstream bytearrayoutputstream) {try {if ( Bytearrayoutputstream! = null) {Bytearrayoutputstream.close ();} if (ObjectOutputStream! = null) {Objectoutputstream.close ();}} catch (Exception e) {e.printstacktrace (); Logger.error ("Close IO resource exception [" + E.getmessage () + "]", E);}} private static void Close (ObjectInputStream objectInputStream, Bytearrayinputstream bytearrayinputstream) {try {if (ObjectInputStream! = null) {Objectinputstream.close ( );} if (bytearrayinputstream! = null) {Bytearrayinputstream.close ();}} catch (Exception e) {e.printstacktrace (); Logger.error ("Close IO resource exception [" + E.getmessage () + "]", E);}} public static byte[] Serialize (Object object) {ObjectOutputStream objectoutputstream = null; Bytearrayoutputstream Bytearrayoutputstream = null;try {bytearrayoutputstream = new Bytearrayoutputstream (); O Bjectoutputstream = new ObjectOutputStream (bytearrayoutputstream); Objectoutputstream.writeobject (object); byte[] bytes = Bytearrayoutputstream.tobytearray (); return bytes;} catch (Exception e) {e.printstacktrace (); Logger.error ("Serialized object exception [" + E.getmessage () + "]", e);} Finally {close (ObjectOutputStream, bytearrayoutputstream);} return null;} @SuppressWarnings ("unchecked") public static <T> T unserialize (byte[] bytes) {if (bytes = = null) return null; Bytearrayinputstream Bytearrayinputstream = Null;objectinputstream ObjectInputStream = null;try {bytearrayinputstream = new Bytearrayinputstream (bytes); ObjectInputStream = new ObjectInputStream (Bytearrayinputstream); return (T) Objectinputstream.readobject ();} catch (Exception e) {e.printstacktrace ();} finally {close (ObjectInputStream, bytearrayinputstream);} return null;}}
The configuration file for Redis is redis.properties as follows:
#redis服务器ip # Redis.ip=192.168.2.107#redis Server port number # Redis.port=6379#********jedis pool parameter settings ********# # Jedis maximum number of allocated objects # Jedis.pool.maxactive=3000#jedis Max Save Idel State object # Jedis.pool.maxidle=1000#jedis Pool no objects returned, Maximum wait time # Jedis.pool.maxwait=1500#jedis when the Borrowobject method is called, does a valid check # jedis.pool.testonborrow=true# Jedis if the Returnobject method is called, does a valid check # jedis.pool.testonreturn=true
MyBatis using Redis level two cache