Mybatis-10
本章目标
1.MyBatis的分页插件【掌握】
2.MyBatis缓存【了解】
3.MyBatis注解【扩展掌握】
4.MyBatis逆向工程【掌握】
具体内容
一.PageHelper插件的使用
官网:https://github.com/pagehelper/Mybatis-PageHelper
使用步骤
第1步:在pom.xml中添加如下依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.11</version>
</dependency>
第2步:在mybatis-config.xml文件中配置分页插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--dialect-->
<property name="helperDialect" value="mysql"></property>
</plugin>
</plugins>
第3步:使用pageHelper
@Test
public void shouldAnswerWithTrue2()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
PageHelper.startPage(2,2);
List<Emp> emps=empMapper.selectEmpsByCoditionWithTrim("s",0);
for(Emp emp:emps){
logger.info(emp);
}
MyBatisUtil.closeSession(sqlSession);
}
备注:startPage方法的第一个参数表示的是当前页,第二参数表示每页的记录数
二.MyBatis缓存
1.什么缓存,为什么要用缓存

使用缓存之后,可以减少对数据库的访问次数,从而提高了查询效率,第一次查如果缓存中没有数据,就去数据库中查,如果缓存中有数据则从缓存中查
2.哪些数据不使用放在缓存中
1)频繁更新的数据
2)财务数据
3.MyBatis的缓存
MyBatis缓存分为一级缓存和二级缓存,一级缓存属于sqlSession级别的缓存,是自带的,二级缓存属于Mapper级别的缓存,默认没有开启,如果使用由程序员来进行配置
3.1 演示一级缓存
@Test
public void testFirstCache()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
Emp emp=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp);
Emp emp1=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession);
}

通过如上的控制台的输出你会发现,第二次并没有发SQL语句,证明第二次是从缓存中查出来的
3.2 四种情况下一级缓存会失效
第1种情况:不同sqlSession
@Test
public void testFirstCacheSx1()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
Emp emp=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp);
SqlSession sqlSession2= MyBatisUtil.createSession();
EmpMapper empMapper2=sqlSession2.getMapper(EmpMapper.class);
Emp emp1=empMapper2.selectEmpByEmpno((short)7369);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession);
}
第2种情况:如果在第一次和第二次之间完成更新操作(增加、删除、修改)的操作
@Test
public void testFirstCacheSx2()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
Emp emp=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp);
Emp e=new Emp();
e.setEmpno((short) 7369);
e.setEname("SMITH");
empMapper.update(e);
Emp emp1=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession);
}
第3种情况:完成刷新操作
@Test
public void testFirstCacheSx3()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
Emp emp=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp);
sqlSession.clearCache();//刷新缓存
Emp emp1=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession);
}
第4种情况:如果查询的id不一样
@Test
public void testFirstCacheSx4()
{
SqlSession sqlSession= MyBatisUtil.createSession();
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
Emp emp=empMapper.selectEmpByEmpno((short)7369);
logger.info(emp);
Emp emp1=empMapper.selectEmpByEmpno((short)7788);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession);
}
3.3 二级缓存
配置二级缓存的步骤
1)在mybatis-config.xml文件中开启二级缓存
<!--开启缓存,默认为true,所以也可以不用写这一步-->
<setting name="cacheEnabled" value="true"></setting>
2)在Mapper映射文件中使用<cache>开启用二级缓存
<mapper namespace="com.woniuxy.dao.DeptMapper">
<!--开启二级缓存-->
<cache></cache>
<select id="selectDeptByNo" parameterType="byte" resultType="dept">
SELECT * FROM dept WHERE deptno=#{deptno}
</select>
<insert id="save" parameterType="dept">
INSERT INTO dept(deptno,dname,loc)VALUE(#{deptno},#{dname},#{loc})
</insert>
</mapper>
3)测试
@Test
public void test5()
{
SqlSession sqlSession= MyBatisUtil.crateSqlSession();
DeptMapper deptMapper=sqlSession.getMapper(DeptMapper.class);
Dept dept=deptMapper.selectDeptByNo((byte)10);
logger.info(dept);
MyBatisUtil.closeSqlSession(sqlSession);
SqlSession sqlSession1=MyBatisUtil.crateSqlSession();
DeptMapper deptMapper1=sqlSession1.getMapper(DeptMapper.class);
Dept dept1=deptMapper1.selectDeptByNo((byte)10);
logger.info(dept1);
MyBatisUtil.closeSqlSession(sqlSession);
}
在运行完程序,之后会报如下错误
提示:
使用二级缓存时,与查询结果映射的Java对象必须实现java.io.Serializable接口的序列化和反序列化操作,如果存在父类,其成员都需要实现序列化接口。实现序列化接口是为了对缓存数据进行序列化和反序列化操作,因此二级缓存数据存储介质多样,不一定在内存,有可能是硬盘或者远程服务器。


如上二级缓存就起到了作用
3.3 关于二级缓存中<cache>属性的解释
flushInterval:刷新间隔。可以被设置为任意的正整数,而且他们代表一个合理的毫秒形式的时间段,默认情况下不设置,也就没有刷新间隔,缓存仅仅调用语句时刷新。
size:缓存数目。可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目,默认值为1024
readOnly:只读。该属性可以被设置为true或者false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势。可以读写的缓存会返回缓存对象拷贝(通过序列化)。这种方式会慢一些,但是安全,因此默认是false.
eviction:回收策略,默认为LRU。有如下几种。
LRU:最近最少使用的策略,移除最长时间不被使用的对象。
FIFO:先进先出策略,按对象进入缓存的顺序来移除它们。
SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象
WEAK:弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象。

补充:关于Java的四种引用
强引用:当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。
软引用:只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象
弱引用:不管当前内存空间足够与否,都会回收它的内存
虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收

浙公网安备 33010602011771号