【Java】MyBatis应用(六)缓存

正文索引 [隐藏]

MaBatis缓存

  • 什么是MyBatis缓存
  • 使用缓存可以减少Java应用与数据库的交互次数,从而提升程序的运行效率。比如查询出id=1的对象,第一次查询出来后会自动该对象保存在缓存中,当下一次查询时直接从缓存中取出该对象即可,无需再次访问数据库

  • MyBatis缓存分类
  • 1、一级缓存:SqlSession级别,默认开启,并且不能关闭
    操作数据库时需要操作SqlSession对象,在对象中有一个HaspMap用于存储缓存数据,不同的SqlSession之间缓存数据区域是互不影响的。
    一级缓存的作用域是SqlSession范围的,当在同一个SqlSession中执行两次相同的sql语句时,第一次执行完毕会将结果保存在缓存中,第二次查询时直接从缓存中获取。
    需要注意的是如果SqlSession执行了DML操作(insert、update、delete),MaBatis必须将缓存清空以保证数据的准确性
    2、二级缓存:Mapper级别,默认关闭,可以开启。
    使用二级缓存的时,多个SqlSession使用同一个Mapper的SQL语句操作数据库,得到的数据会存在二级缓存区,同样是使用HaspMap进行数据存储,相比较于一级缓存,二级缓存范围更大,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
    二级缓存是多个SqlSession共享的,其作用域是Mapper的同一个namespace,不同的SqlSession两次执行相同的namespace下的Sql语句时,参数也相等,则第一次执行成功后会将数据保存在二级缓存中,第二次可直接从二级缓存中取出数据。
    代码

  • 一级缓存
  • package com.mybatistest.test;
    import com.mybatistest.entity.Account;
    import com.mybatistest.repository.AccountRepository;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import java.io.InputStream;
    public class Test5 {
    public static void main(String[] args) {
    //加载配置文件
    InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class);
    Account account = accountRepository.findById(1L);
    System.out.println(account);
    sqlSession.close();
    sqlSession = sqlSessionFactory.openSession();
    accountRepository = sqlSession.getMapper(AccountRepository.class);
    account = accountRepository.findById(1L);
    System.out.println(account);
    }
    }
  • 二级缓存
  • 1、MyBatis自带的二级缓存

  • config.xml中配置开启二级缓存
  • <settings>
    <!-- 打印SQL-->
    <setting name="logImpl" value="STDOUT_LOGGING" />
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
    </settings>
  • Mapper.xml中配置二级缓存
  • <cache></cache>
  • 实体类实现序列化接口
  • package com.mybatistest.entity;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import java.io.Serializable;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Account implements Serializable {
    private long id;
    private String username;
    private String password;
    private Integer age;
    }

    2、ehcache二级缓存

  • pom.xml添加相关依赖
  • <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
    </dependency>
    <dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.0.0</version>
    </dependency>
  • 添加eheache.xml
  • <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore/>
    <defaultCache
    maxElementsInMemory="1000"
    maxElementsOnDisk="10000000"
    eternal="false"
    overflowToDisk="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU">
    </defaultCache>
    </ehcache>
  • 在config.xml中配置开启二级缓存
  • <settings>
    <!-- 打印SQL-->
    <setting name="logImpl" value="STDOUT_LOGGING" />
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
    </settings>
  • 在Mapper.xml配置二级缓存
  • <cache type="org.mybatis.caches.ehcache.EhcacheCache">
    <!-- 缓存创建后,最后一次访问缓存的时间至缓存失效的时间间隔 -->
    <property name="timeToIdleSeconds" value="3600"/>
    <!-- 缓存自创建时间起至失效的时间间隔 -->
    <property name="timeToLiveSeconds" value="3600"/>
    <!-- 缓存的回收策略 LRU表示移除近期最少使用的对象 -->
    <property name="memoryStoreEvictiomPolicy" value="LRU"/>
    </cache>
  • 实体类不需要实现序列化接口
blank