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.什么缓存,为什么要用缓存

20200706_165508_123.png

使用缓存之后,可以减少对数据库的访问次数,从而提高了查询效率,第一次查如果缓存中没有数据,就去数据库中查,如果缓存中有数据则从缓存中查

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);

    }

 

20200706_170807_704.png

通过如上的控制台的输出你会发现,第二次并没有发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);

}

在运行完程序,之后会报如下错误20200707_091330_434.png

提示:

使用二级缓存时,与查询结果映射的Java对象必须实现java.io.Serializable接口的序列化和反序列化操作,如果存在父类,其成员都需要实现序列化接口。实现序列化接口是为了对缓存数据进行序列化和反序列化操作,因此二级缓存数据存储介质多样,不一定在内存,有可能是硬盘或者远程服务器。

20200707_091350_236.png

20200707_091409_058.png

如上二级缓存就起到了作用

3.3 关于二级缓存中<cache>属性的解释

flushInterval:刷新间隔。可以被设置为任意的正整数,而且他们代表一个合理的毫秒形式的时间段,默认情况下不设置,也就没有刷新间隔,缓存仅仅调用语句时刷新。

size:缓存数目。可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目,默认值为1024

readOnly:只读。该属性可以被设置为true或者false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势。可以读写的缓存会返回缓存对象拷贝(通过序列化)。这种方式会慢一些,但是安全,因此默认是false.

eviction:回收策略,默认为LRU。有如下几种。

LRU:最近最少使用的策略,移除最长时间不被使用的对象。

FIFO:先进先出策略,按对象进入缓存的顺序来移除它们。

SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象

WEAK:弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象。

20200707_095627_710.png

补充:关于Java的四种引用

强引用:当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足的问题。

软引用:只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象

弱引用:不管当前内存空间足够与否,都会回收它的内存

虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收

 

posted @ 2020-10-09 14:17  Mistory  阅读(140)  评论(0)    收藏  举报