缓存
文件的读取速度慢于内存,所以有些查询过一次的数据,会临时存储在内存中。
二次查询会先判断内存里是否存在,存在的话就直接读取内在的数据,不存在才去读数据库
Emp实体类:
package cn.et.mybatis.lesson05.buff;
import java.io.Serializable;
public class Emp implements Serializable{
private String empno;
private String ename;
private String sal;
public String getEmpno() {
return empno;
}
public void setEmpno(String empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getSal() {
return sal;
}
public void setSal(String sal) {
this.sal = sal;
}
@Override
public String toString() {
return "Emp [empno=" + empno + ", ename=" + ename + ", sal=" + sal
+ "]";
}
}
EmpMapper接口
package cn.et.mybatis.lesson05.buff;
public interface EmpMapper {
/**
* 测试一级缓存
* @param empno
* @return
*/
public Emp queryEmp(String empno);
/**
* 测试二级缓存
* @param empno
* @return
*/
public Emp queryEmp2(String empno);
}
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">
<!--
接口映射
namespace必需跟接口的全名一致
-->
<mapper namespace="cn.et.mybatis.lesson05.buff.EmpMapper">
<select id="queryEmp" resultType="cn.et.mybatis.lesson05.buff.Emp">
select * from emp where empno=#{0}
</select>
<!--
加上cache标签就开启mybatis的二级缓存了
eviction属性
FIFO 将队列最右端的数据T出内在 为先进先去
LFU 使用次数最少的T出内存 这个在这里不支持
LRU 最近使用次数最少的
-->
<cache eviction="LRU"></cache>
<select id="queryEmp2" resultType="cn.et.mybatis.lesson05.buff.Emp">
select * from emp where empno=#{0}
</select>
</mapper>
TestMybatis测试类
package cn.et.mybatis.lesson05.buff;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
public class TestMybatis {
public static SqlSessionFactory getSqlSessionFactory(){
String resource = "/cn/et/mybatis/lesson05/mybatis.xml";
InputStream inputStream = TestMybatis.class.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
/**
* 测试一级缓存
* 一级缓存是session级别的缓存 数据被缓存在session对象中
* 必须使用同一个session
* 发起了二次请求,第一次是去数据库查找,查完之后就会缓存在
* session对象中,第二查询的时候会先去session对象中查找,看有没有
* 这个数据,如果有的话就直接返回出去,不会再去数据库中查询。
* 增加了效率
* 测试动态Where
*/
// @Test
public void testOneBuff(){
SqlSession session = getSqlSessionFactory().openSession();;
EmpMapper emp = session.getMapper(EmpMapper.class);
Emp result1 = emp.queryEmp("8000");
Emp result2 = emp.queryEmp("8000");
System.out.println(result1==result2);
}
/**
* 测试二级缓存
* 二级缓存就是缓存在SqlSessionFactory对象里
* 这里我们先生成了一个SqlSession对象,并查询了一条语句
* 然后陈SqlSession对象关闭了,那么这时缓存在SqlSession对象
* 里的数据就会丢给SqlSessionFactory对象。
*
* 在查询条二件sql语句的时候会先去当前的SqlSession里看有没有需要查询的数据
* 然后再去SqlSessionFactory对象中找,这时SqlSessionFactory有这条数据,
* 便直接返回回去了,第二次查询没有再去数据库查询了
*
* Emp实体类要实现Serializable接口,不然会报错
* 二个对象的地址是不相等的,但实际只去数据库查询了一次。
*/
@Test
public void testTwoBuff(){
SqlSessionFactory Factory = getSqlSessionFactory();
SqlSession session1 = Factory.openSession();
EmpMapper emp1 = session1.getMapper(EmpMapper.class);
Emp result1 = emp1.queryEmp2("8000");
session1.close();
SqlSession session2 = Factory.openSession();
EmpMapper emp2 = session2.getMapper(EmpMapper.class);
Emp result2 = emp2.queryEmp2("8000");
System.out.println(result1==result2);
}
}