SSM系列4 Mybatis缓存策略与分页组件PageHelper

继上一篇笔记 SSM系列3 Mybatis快速上手,今天学习了一下Mybatis的分页组件与缓存策略,直接上干货

Mybatis的缓存策略

Mybatis缓存策略有两级缓存:
一级缓存:默认开启,缓存范围为一次SqlSession会话,session关闭,该缓存即清空
二级缓存:手动开启,缓存范围为mapper的namespace中,比一级缓存范围大,生存时间长
一级缓存无论何种操作,进行了commit之后都会被清空
二级缓存的commit的操作,只有在写操作commit之后才会被清空,查询后的commit操作不会清空缓存

一级缓存

代码演示:

/*缓存测试*/
@Test
public void testFindById(){
    SqlSession session = null;
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session1-对象1:"+goods);
        Goods goods2 = session.selectOne("goods.findById",739);
        System.out.println("session1-对象2:"+goods2);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session2-对象1:"+goods);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
}

我们看如下结果,在同一个session中,进行两次查询,但是只去数据库查询了一次,并且两次接收到的对象是同一个对象,在第二个session中查询同一条数据,又去数据库查询了一次,这说明一级缓存的作用域是一个session会话周期
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第1张图片

commit 清空缓存测试

/*缓存测试*/
@Test
public void testFindById(){
    SqlSession session = null;
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session1-对象1:"+goods);
        session.commit();//清空缓存
        Goods goods2 = session.selectOne("goods.findById",739);
        System.out.println("session1-对象2:"+goods2);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
}

看下图结果,去数据库进行了两次查询,并且对象也不一样,所以commit清空缓存的成立的
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第2张图片

禁用缓存

一级缓存可以使用flushCache禁用,用法是在相关的mapper.xml的Sql标签后面加上flushCache=“true”
flushCache:强制清空缓存,并且该Sql执行后无论得到什么结果都不会对其进行缓存

<select id="findById" parameterType="Integer" resultType="com.zhangyx.mybatis.entity.Goods" flushCache="true">
   select * from t_goods where goods_id = #{value }
select>

继续用刚才的测试代码测试,结果如下,下面我也不说太多了,自己看代码,看结果
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第3张图片

二级缓存

二级缓存开启就需要一些配置了
mybatis-config.xml里settings里增加setting项,开启二级缓存


<setting name="cacheEnabled" value="true"/>

相应的mapper.xml我这里是goods.xml里增加cache标签


<cache eviction="LRU" flushInterval="6000000" size="512" readOnly="true"/>

测试

记得把flushCache选项去掉,这个在二级缓存里也是起作用的

/*缓存测试*/
@Test
public void testFindById(){
    SqlSession session = null;
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session1-对象1:"+goods);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session2-对象1:"+goods);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
}

结果:第二次也没有去数据库进行查询,直接将第一次查询的缓存对象取出来了
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第4张图片

缓存清空策略

一级缓存清空策略上面已经说过了,利用commit,与flushCache可以清空缓存
二级缓存不一样喽,可以利用flushCache="true"清空缓存,useCache="false"禁用缓存
flushCache刚才已经说过了,这里不再说了,大家可以自己测试,这里说一下useCache="false"禁用缓存,跟flushCache一样,在Sql相关标签上加上即可

<select id="findById" parameterType="Integer" resultType="com.zhangyx.mybatis.entity.Goods" useCache="false">
        select * from t_goods where goods_id = #{value }
select>

由于一级缓存的存在,这里测试需要放在两个session会话里

/*缓存测试*/
@Test
public void testFindById(){
    SqlSession session = null;
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session1-对象1:"+goods);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",739);
        System.out.println("session2-对象1:"+goods);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
}

两次查询,两个对象
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第5张图片

写操作缓存策略

写操作都没有缓存,因为写操作上面的flushCache默认是开启的,就以更新为例看一下

@Test
public void testUpdate(){
    SqlSession session = null;
    //openSession创建一个新的Sqlsession对象,Sqlsession提供了增删改查的方法调用
    try {
        session = sessionFactory.openSession();
        Goods goods = session.selectOne("goods.findById",2675);
        System.out.println(goods);
        goods.setTitle("数据更新测试");
        goods.setSubTitle("数据更新测试第二标题");
        goods.setCategoryId(1);
        goods.setCurrentPrice(1000f);
        goods.setDiscount(2f);
        goods.setIsFreeDelivery(1);
        goods.setOriginalCost(20f);
        session.update("goods.update", goods);
//            session.commit();//清队缓存干扰去掉
    }catch (Exception e){
        e.printStackTrace();
        session.rollback();
    }finally {
        if(session != null){
            //将Connection归还到连接池供其他Session重用
            session.close();
        }
    }
    try {
        session = sessionFactory.openSession();
        Goods goods1 = session.selectOne("goods.findById",2675);
        System.out.println(goods1);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            session.close();
        }
    }
}

SSM系列4 Mybatis缓存策略与分页组件PageHelper_第6张图片

使用分页插件粗略步骤

其实官网有详细教程:https://pagehelper.github.io/docs/howtouse/
1.引入PageHelper与jsqlparser核心jar包
2.mybatis-config.xml增加有关PageHelper的Plugin配置
3.代码中查询数据库代码的上方直接使用PageHelper.startPage()自动分页

pom.xml引入Mybatis分页组件PageHelper


<dependency>
	<groupId>com.github.pagehelpergroupId>
	<artifactId>pagehelperartifactId>
	<version>5.1.4version>
dependency>

<dependency>
	<groupId>com.github.jsqlparsergroupId>
	<artifactId>jsqlparserartifactId>
	<version>0.9.5version>
dependency>

mybatis-config.xml增加plugin配置

<plugins>
	<plugin interceptor="com.github.pagehelper.PageInterceptor">
    	
    	<property name="helperDialect" value="mysql"/>
	    
    	<property name="reasonable" value="true"/>
    plugin>
plugins>

测试

@Test
public void testFindAll(){
    SqlSession session = null;
    //openSession创建一个新的Sqlsession对象,Sqlsession提供了增删改查的方法调用
    try {
        session = sessionFactory.openSession();
        //selectList用于查询多条数据
        //表.xml里对应的namespace.sqlId
        //分页组件,直接在查询代码上方加入PageHelper.startPage()即可
        PageHelper.startPage(0,10);
        List<Goods> list = session.selectList("goods.findAll");
        for (Goods goods : list){
            System.out.println(goods.getTitle());
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session != null){
            //将Connection归还到连接池供其他Session重用
            session.close();
        }
    }
}

运行结果
SSM系列4 Mybatis缓存策略与分页组件PageHelper_第7张图片

如果分页插件里指定的跟自己使用的数据库不一样,比如说指定了oracle,但是我们使用的是mysql会发生什么情况呢
我们看到,虽然指定的数据库错了,但是分页组件还是按照oracle的形式把要其所用的sql语句组装了起来,只不过组装的是oracle可以用的分页语句

SSM系列4 Mybatis缓存策略与分页组件PageHelper_第8张图片
Mybatis告一段落,但是在实际项目开发中,sqlSessionFactory不是这样使用的,需要配置到xml文件里的,会在我后面的笔记:Spring SpringMVC Mybatis FreeMarker 整合里作记录

你可能感兴趣的:(mybatis,SpringMVC,java)