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 自定义配置信息
posted @ 2023-03-20 12:35  lwx_R  阅读(9)  评论(0编辑  收藏  举报