first, the MyBatis cache
Like most ORM layer frameworks, MyBatis naturally provides support for first-level caching and level two caching. This is the role and definition of the first-level cache and the level two cache.
1, the first cache is the sqlsession level of caching. The Sqlsession object needs to be constructed when manipulating the database, and there is a (memory region) data structure (HASHMAP) in the object to store the cached data. The cached data regions (HASHMAP) between different sqlsession are not affected by each other.
Second-level caching is the mapper level of caching, multiple sqlsession to operate the same mapper SQL statements, multiple sqlsession to operate the database to get data there will be a level two cache area, multiple sqlsession can share two levels of cache, Second-level caching is a cross sqlsession.
2, the scope of the first cache is the same sqlsession, execute the same SQL statement two times in the same sqlsession, the first execution will write the data queried in the database to the cache (memory), and the second time the data obtained from the cache will no longer be queried from the database, thus increasing the efficiency of the query. When a sqlsession is finished, the first-level cache in the sqlsession does not exist. MyBatis the first-level cache is turned on by default.
The second-level cache is shared by multiple sqlsession, and its scope is the same namespace of mapper, with different sqlsession executing SQL statements under the same namespace two times and passing parameters to SQL, the same as the final execution of the same SQL statement. After the first execution, the data queried in the database is written to the cache (memory), and the second time the data obtained from the cache will no longer be queried from the database, thus increasing the efficiency of the query. MyBatis the level two cache is not turned on by default needs to be configured to open level two caching in the setting global parameter.
In general, when we integrate MyBatis and spring, the mybatis-spring package automatically sqlsession, and spring uses a template method to encapsulate operations such as select () through dynamic proxy sqlsessionproxy. Each select () query automatically executes opensession () and calls the close () method after Close (), which is equivalent to generating a new session instance, so we don't have to manually turn off this session (). Of course, you cannot use a mybatis cache, meaning that a mybatis cache is not useful in spring.
Therefore, we generally implement the MyBatis level two cache in the project, although the MyBatis with two-level caching, but if the actual cluster environment, the use of the two-level cache is only for a single node, so we use the distributed two-level caching function. General cache NoSQL databases such as Redis,mancache, or ehcache, can be implemented to better serve the ORM query in the Tomcat cluster.
implementation of the level two cache of MyBatis
The following mainly through the Redis implementation of the MyBatis two-level caching function. 1, the configuration file to open level two cache
<setting name= "cacheenabled" value= "true"/>
The default level two cache is turned on.
2, realize the MyBatis cache interface
MyBatis provides a third-party cache implementation interface, we custom Mybatisrediscache implementation cache interface, the code is as follows:
/** * Creation Date: January 7, 2016 morning 11:40:00 * * MyBatis two cache implementation class * * @author Andy * @version 2.2/public class Mybatisredisc
Ache implements Cache {private static final Logger LOG = Logger.getlogger (Mybatisrediscache.class);
Private final Readwritelock Readwritelock = new Reentrantreadwritelock (true); Private Redistemplate<serializable, serializable> redistemplate = (redistemplate<serializable, Serializable
>) Springcontextholder.getbean ("Redistemplate");
Private String ID;
Private Jdkserializationredisserializer Jdkserializer = new Jdkserializationredisserializer (); Public Mybatisrediscache (final String ID) {if (id = = null) {throw new IllegalArgumentException ("Cache instances Requir
E an ID ");
} log.info ("Redis Cache ID" + ID);
This.id = ID;
@Override public String getId () {return this.id; @Override public void Putobject (object key, object value) {if (value!= null) {Redistemplate.opsforvalue (). Set (k Ey.tostring (), JdkserializEr.serialize (value), 2, timeunit.days); @Override public Object GetObject (object key) {try {if (key!= null) {Object obj = Redistemplate.opsforv
Alue (). Get (Key.tostring ());
Return Jdkserializer.deserialize ((byte[]) obj);
The catch (Exception e) {log.error ("Redis");
return null; @Override public Object Removeobject (object key) {try {if (key!= null) {Redistemplate.expire key.tostring (
), 1, timeunit.seconds);
The catch (Exception e) {} return null; @Override public void Clear () {//jedis nonsupport} @Override public int getsize () {Long size = Redistempla Te.getmasterredistemplate (). Execute (new rediscallback<long> () {@Override public Long Doinredis (redisconnectio
n connection) throws DataAccessException {return connection.dbsize ();
}
});
return Size.intvalue ();
@Override public Readwritelock Getreadwritelock () {return this.readwritelock; }
}
3, two-level cache of practical
We need to serialize all the entity classes and then add the custom cache feature to the mapper.
<cache
type= "Org.andy.shop.cache.MybatisRedisCache"
eviction= "
LRU" flushinterval= "6000000" Size= "1024"
readonly= "false"
/>
4, storage in the Redis
Redis automatically uses the sql+ condition +hash as the key value, and the query result as value, and only if all the parameters in the request are met, then the level two cache in Redis is used. Its query results are as follows: