MyBatis官方文档
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两级缓存,一级缓存和二级缓存。
- | - | - | - |
---|---|---|---|
localCacheScope | MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. | SESSION/STATEMENT | SESSION |
CacheTest.java
public class CacheTest {
@Test
public void testFirstCache() throws IOException {
SqlSessionFactory ssf = Tools.getSqlSessionFactory("c03/mybatis-config.xml");
SqlSession session = ssf.openSession();
try {
EmployeeMapper em = session.getMapper(EmployeeMapper.class);
Employee e1 = em.getEmpById(1);
System.out.println(e1);
Employee e2 = em.getEmpById(1);
System.out.println(e2);
System.out.println("e1 == e2 : " + (e1 == e2));
session.commit();
} finally {
session.close();
}
}
}
输出结果:
DEBUG 08-02 22:50:35,092 ==> Preparing: select * from employee where id = ? (BaseJdbcLogger.java:145)
DEBUG 08-02 22:50:35,192 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:145)
DEBUG 08-02 22:50:35,260 <== Total: 1 (BaseJdbcLogger.java:145)
Employee [id=1, lastName=jallen2, [email protected], gender=1, department=null]
Employee [id=1, lastName=jallen2, [email protected], gender=1, department=null]
e1 == e2 : true <-------------e1和e2指向相同的对象
同一次会话期间只要查询过的数据都会保存在当前SqlSession的一个Map中
一级缓存失效的四种情况:
cache标签的属性:
使用步骤:
mybatis-config.xml
Employee.java
public class Employee implements Serializable{
private static final long serialVersionUID = -7390587151857533202L;
EmployeeMapper.xml
<mapper namespace="club.coderhome.c03.mapper.dao.EmployeeMapper">
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024">cache>
CacheTest.java
public class CacheTest {
@Test
public void testSecondCache() throws IOException {
SqlSessionFactory ssf = Tools.getSqlSessionFactory("c05/mybatis-config.xml");
SqlSession session = ssf.openSession();
SqlSession session2 = ssf.openSession();
try {
EmployeeMapper em = session.getMapper(EmployeeMapper.class);
Employee e1 = em.getEmpById(1);
System.out.println(e1);
session.close();
EmployeeMapper em2 = session2.getMapper(EmployeeMapper.class);
Employee e2 = em2.getEmpById(1);
System.out.println(e2);
System.out.println("e1 == e2 : " + (e1 == e2));
} finally {
session2.close();
}
}
输出结果:
DEBUG 08-03 01:13:02,575 Cache Hit Ratio [club.coderhome.c03.mapper.dao.EmployeeMapper]: 0.0 (LoggingCache.java:62)
DEBUG 08-03 01:13:03,945 ==> Preparing: select * from employee where id = ? (BaseJdbcLogger.java:145)
DEBUG 08-03 01:13:04,081 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:145)
DEBUG 08-03 01:13:04,186 <== Total: 1 (BaseJdbcLogger.java:145)
Employee [id=1, lastName=jallen2, [email protected], gender=1, department=null]
DEBUG 08-03 01:13:04,218 Cache Hit Ratio [club.coderhome.c03.mapper.dao.EmployeeMapper]: 0.5 (LoggingCache.java:62)
Employee [id=1, lastName=jallen2, [email protected], gender=1, department=null]
e1 == e2 : false
package org.apache.ibatis.cache;
import java.util.concurrent.locks.ReadWriteLock;
public interface Cache {
String getId();
void putObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);
void clear();
int getSize();
ReadWriteLock getReadWriteLock();
}
步骤:
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.2.1version>
dependency>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="C:\\ehcache" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
defaultCache>
ehcache>
演示:
DepartmentMapper.xml
<mapper namespace="club.coderhome.c03.mapper.dao.DepartmentMapper">
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
CacheTest.java
public class CacheTest {
@Test
public void testEhcache() throws IOException {
SqlSessionFactory ssf = Tools.getSqlSessionFactory("c05/mybatis-config.xml");
SqlSession session = ssf.openSession();
SqlSession session2 = ssf.openSession();
try {
DepartmentMapper dm = session.getMapper(DepartmentMapper.class);
Department dp = dm.getDeptById(1);
System.out.println(dp);
session.close();
DepartmentMapper dm2 = session2.getMapper(DepartmentMapper.class);
Department dp2 = dm2.getDeptById(1);
System.out.println(dp2);
} finally {
session2.close();
}
}
另外:
参照缓存: 若想在命名空间中共享相同的缓存配置和实例。可以使用 cache-ref 元素来引用另外一个缓存。
<mapper namespace="club.coderhome.mybatis.dao.DepartmentMapper">
<cache-ref namespace="club.coderhome.mybatis.dao.EmployeeMapper"/>