Mybatis缓存
1.一级缓存
同一个SqlSession对象第一次执行查询语句,把结果写入一级缓存
之后没有更新插入删除操作,执行相同的查询语句,会读取一级缓存内数据
1.1 原理
SqlSession级别的缓存。创建SqlSession时,对象引入HashMap作为储存数据区域。
key是SQL语句、条件、statement组成的唯一值
value是查询的结果对象
不同SqlSession之间HashMap不影响
1.2 应用
1.2.1 log4j日志配置
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
- log4j.properies 配置文件
log4j.rootLogger = ERROR,stdout
#mybatis???? namespace?
log4j.logger.mapper.StudentMapper = DEBUG
#???????
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p[%t] - %m%n
1.2.2 Test类
@Test
public void Test(){
String resource = "config.xml";
try{
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(in);
SqlSession sqlSession=ssf.openSession();
String statement="mapper.StudentMapper.getStudentBySid";
Student student = sqlSession.selectOne(statement,1);
System.out.println(student);
Student student1 = sqlSession.selectOne(statement,1);
System.out.println(student1);
sqlSession.commit();
sqlSession.close();
}catch (Exception e){
e.printStackTrace();
}
}
2.二级缓存
2.1 原理
作用域是Mapper,可以跨多个SqlSession,多个SqlSession操作同一个Mapper的Sql语句,共用二级缓存
HashMap与一级缓存一样
可以自定义缓存源
以namespace区分Mapper,SqlSesion执行查询,没有更新删除插入,别的SqlSession执行相同查询,从缓存拿到
2.2 应用
2.2.1 开启二级缓存
- 配置文件
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- Mapper.xml
<cache></cache>
默认特性:
- 缓存使用LRU算法收回
- 没有刷新间隔,缓存不会以任何时间顺序来刷新
- 缓存会存储列表集合或对象的1024个引用
- 缓存可读写,对象检索不是共享的,可以安全调用
2.2.2 实体类序列化
public class Student implements Serializable
2.2.3 测试类
@Test
public void cache(){
String resource = "config.xml";
try{
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(in);
SqlSession sqlSession1 = ssf.openSession();
SqlSession sqlSession2 = ssf.openSession();
String statement="mapper.StudentMapper.getStudentBySid";
Student student1 = sqlSession1.selectOne(statement,1);
System.out.println(student1);
// 是否在新的SQL查询之前没有关闭上一个SqlSession,导致命中了一级缓存而不需要查询二级缓存
sqlSession1.commit();
sqlSession1.close();
Student student2 = sqlSession2.selectOne(statement,1);
System.out.println(student2);
sqlSession2.commit();
sqlSession2.close();
}catch (Exception e){
e.printStackTrace();
}
}
3.整合EhCache
3.1 依赖
<!-- EhCache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.8</version>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.3</version>
</dependency>
3.2 ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="D:/cache"></diskStore>
<defaultCache
maxElementsInMemory="1"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
- diskStore 指定缓存数据转移到磁盘,path指定存储位置
- defaultCache 指定默认缓存配置信息
- cache 自定义配置信息