前言:
MyBatis中一级缓存和二级缓存默认都是开启的;
一级缓存是Session级别的缓存,二级缓存是SqlSessionFactory级别的缓存
一级缓存:
package cn.et.lesson05;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* 缓存:
* 数据交换的缓冲区;当要读取数据时,会首先从内存中查找需要的数据,如果找到了就直接执行;
* 找不到的话再从数据库中找,从数据库中找出来后返回数据并将其缓存于内存中;
*
* 缓存算法: FIFO 先进先出算法 内存不足时 先存储进去数据 会先被剔除
* LRU 最近使用次数最少算法 内存不足时 最近使用次数最少被剔除
* LFU 使用次数最少算法 内存不足时 使用次数最少的被剔除
*
* @author Administrator
*
*/
public class TestMybatis {
private static SqlSessionFactory getSqlSessionFactory() {
//因为需要的mybatis.xml文件 不在同一层目录 所以这里才使用 cn.et.lesson01.TestMybatis
InputStream is = TestMybatis.class.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
return factory;
}
/**
* 一级缓存
* @param args
*/
public static void main(String[] args) {
SqlSessionFactory factory = getSqlSessionFactory();
//打开第一个SqlSession
SqlSession sqlSession1 = factory.openSession();
//获取第一个EmpMapper实例
EmpMapper dm = sqlSession1.getMapper(EmpMapper.class);
//发起第一次sql查询
Emp emp = dm.selectEmp("7369");
//获取第二个EmpMapper实例
EmpMapper dm1 = sqlSession1.getMapper(EmpMapper.class);
//发起第二次sql查询
Emp emp1 = dm1.selectEmp("7369");
System.out.println(dm==dm1);
System.out.println(emp == emp1);
System.out.println("\r-----------------分割线----------------\r");
//打开第二个SqlSession
SqlSession sqlSession2 = factory.openSession();
//通过sqlSession2获取EmpMapper实例
EmpMapper em = sqlSession2.getMapper(EmpMapper.class);
Emp selectEmp = em.selectEmp("7369");
}
}
Run:
从运行结果可以很明显看出 一级缓存是Session级别的缓存并且存放在Session中
因此当不同的Session发起相同的select语句时发起了两次查询
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Opening JDBC Connection
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Created connection 1448851814.
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@565bb966]
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Preparing: select * from emp where empno = ?
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Parameters: 7369(String)
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] <== Total: 1
false
true
-----------------分割线----------------
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Opening JDBC Connection
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Created connection 342983234.
2017-06-16 20:42:00 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@14718242]
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Preparing: select * from emp where empno = ?
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Parameters: 7369(String)
2017-06-16 20:42:00 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] <== Total: 1
二级缓存:
实体类必须实现Serializable
emp_mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.et.lesson05.EmpMapper">
<!--<cache></cache> 启用二级缓存 属性默认 -->
<cache></cache>
<select id="selectEmp" resultType="cn.et.lesson05.Emp">
select * from emp where empno = #{0}
</select>
</mapper>
Test
/**
* 二级缓存
* @param args
*/
public static void main(String[] args) {
SqlSessionFactory factory = getSqlSessionFactory();
SqlSession session = factory.openSession();
EmpMapper dm = session.getMapper(EmpMapper.class);
Emp emp = dm.selectEmp("7369");
//开启二级缓存后 关闭session时
//session中一级缓存的数据会自动发往二级缓存
session.close();
//打开第二个SqlSession
SqlSession session2 = factory.openSession();
//通过sqlSession2获取EmpMapper实例
EmpMapper em = session2.getMapper(EmpMapper.class);
Emp selectEmp = em.selectEmp("7369");
}
Run
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Opening JDBC Connection
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Created connection 110640533.
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@6983d95]
2017-06-16 21:28:05 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Preparing: select * from emp where empno = ?
2017-06-16 21:28:05 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] ==> Parameters: 7369(String)
2017-06-16 21:28:05 DEBUG [cn.et.lesson05.EmpMapper.selectEmp] <== Total: 1
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@6983d95]
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@6983d95]
2017-06-16 21:28:05 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Returned connection 110640533 to pool.
2017-06-16 21:28:05 DEBUG [cn.et.lesson05.EmpMapper] Cache Hit Ratio [cn.et.lesson05.EmpMapper]: 0.5