zoukankan      html  css  js  c++  java
  • mybatis缓存之一级缓存(一)

    对于mybatis框架。仿佛工作中一直是在copy着使用。对于mybatis缓存。并没有一个准确的认知。趁着假期。学习下mybatis的缓存。这篇主要学习mybatis的一级缓存。

    为什么使用缓存

    其实,大家工作久了,就知道很多瓶颈就是在数据库上。

    初识mybatis一级缓存

    当然我们还是通过代码来认识下mybatis的一级缓存

    代码演示

    详细代码见github,这里只展示重要的代码片段

    1. tempMapper.xml
        <select id="getById" resultType="entity.TempEntity">
           select * from  temp where id = #{id}
        </select>
    
    1. TempTest
    public class TempTest {
    
        Logger logger = Logger.getLogger(this.getClass());
        @Test
        public  void test() throws IOException {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = build.openSession();
            TempEntity tempEntity1 = sqlSession.selectOne("dao.TempDao.getById", 1);
            logger.info(tempEntity1);
            TempEntity tempEntity2 = sqlSession.selectOne("dao.TempDao.getById", 1);
            logger.info(tempEntity2);
            logger.info(tempEntity1 == tempEntity2);
        }
    }
    

    3.运行结果

    2020-06-26 08:57:37,453 DEBUG [dao.TempDao.getById] - ==>  Preparing: select * from temp where id = ? 
    2020-06-26 08:57:37,513 DEBUG [dao.TempDao.getById] - ==> Parameters: 1(Integer)
    2020-06-26 08:57:37,538 DEBUG [dao.TempDao.getById] - <==      Total: 1
    2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
    2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
    2020-06-26 08:57:37,538 INFO [TempTest] - true
    
    1. 总结

    4.1 从上面的结果,我们可以看到,第二次查询的时候,就直接没有查询数据库,并且返回的是同一个对象。证明第二次走的就是缓存。
    4.2 一级缓存是默认开启的。我们并没有在代码中配置任何关于缓存的配置
    4.3 代码回顾

    mybatis一级缓存命中原则

    mybatis是怎么样判断某两次查询是完全相同的查询?

    1.statementId

    1.1 mapper.xml

        <select id="getById1" resultType="entity.TempEntity">
           select * from  temp where id = #{id}
        </select>
    
        <select id="getById2" resultType="entity.TempEntity">
           select * from  temp where id = #{id}
        </select>
    

    1.2 test

        @Test
        public  void test() throws IOException {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = build.openSession();
            TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
            logger.info(tempEntity1);
            TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById2", 1);
            logger.info(tempEntity2);
            logger.info(tempEntity1 == tempEntity2);
        }
    

    1.3 结果

    2020-06-26 09:19:09,926 DEBUG [dao.Temp2Dao.getById1] - ==>  Preparing: select * from temp where id = ? 
    2020-06-26 09:19:09,957 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
    2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById1] - <==      Total: 1
    2020-06-26 09:19:09,969 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
    2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById2] - ==>  Preparing: select * from temp where id = ? 
    2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - ==> Parameters: 1(Integer)
    2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - <==      Total: 1
    2020-06-26 09:19:09,971 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
    

    1.4 总结
    要求查询的statementId必须完全相同,否则无法命中缓存,即时两个查询语句、参数完全相同

    2.查询参数

    我们用不同的参数查询,一个传1 一个传2
    2.1 test

        @Test
        public  void testParam() throws IOException {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = build.openSession();
            TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
            logger.info(tempEntity1);
            TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById1", 2);
            logger.info(tempEntity2);
            logger.info(tempEntity1 == tempEntity2);
        }
    

    2.2 结果

    2020-06-26 09:24:33,107 DEBUG [dao.Temp2Dao.getById1] - ==>  Preparing: select * from temp where id = ? 
    2020-06-26 09:24:33,148 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
    2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - <==      Total: 1
    2020-06-26 09:24:33,162 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
    2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - ==>  Preparing: select * from temp where id = ? 
    2020-06-26 09:24:33,163 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 2(Integer)
    2020-06-26 09:24:33,164 DEBUG [dao.Temp2Dao.getById1] - <==      Total: 1
    2020-06-26 09:24:33,164 INFO [TempTest] - TempEntity{id=2, value1='22222', value2='bbbb'}
    2020-06-26 09:24:33,164 INFO [TempTest] - false
    
    
    

    2.3 总结

    要求传递给sql的传递参数相同,否则不会命中缓存

    3.分页参数

    3.1 传不同的分页参数

        @Test
        public  void testPage() throws IOException {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = build.openSession();
            RowBounds rowBounds1 = new RowBounds(0,1);
            List<TempEntity> tempEntity1 = sqlSession.selectList("dao.Temp2Dao.getList", null,rowBounds1);
            logger.info(tempEntity1);
            RowBounds rowBounds2 = new RowBounds(0,2);
            List<TempEntity> tempEntity2 = sqlSession.selectList("dao.Temp2Dao.getList",null, rowBounds2);
            logger.info(tempEntity2);
            logger.info(tempEntity1 == tempEntity2);
        }
    

    3.2 结果

    2020-06-26 10:10:33,060 DEBUG [dao.Temp2Dao.getList] - ==>  Preparing: select * from temp where 1=1 
    2020-06-26 10:10:33,101 DEBUG [dao.Temp2Dao.getList] - ==> Parameters: 
    2020-06-26 10:10:33,116 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}]
    2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==>  Preparing: select * from temp where 1=1 
    2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==> Parameters: 
    2020-06-26 10:10:33,118 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}, TempEntity{id=2, value1='22222', value2='bbbb'}]
    2020-06-26 10:10:33,118 INFO [TempTest] - false
    

    3.3 总结

    要求分页参数必须相同,否则无法命中缓存。缓存的粒度是整个分页查询结果,而不是结果中的每个对象

    4. sql语句

    4.1 mapper文件

        <select id="getById" resultType="entity.TempEntity">
           select * from  temp 
           <where>
               <if test="type ==1">
               id = #{id}
                </if>
               <if test="type ==2">
                   1=1 and id = #{id}
               </if>
           </where> 
        </select>
    

    这个就不测试了。
    4.2 总结
    要求传递给jdbc的sql 必须完全相同。就算是1=1 不起作用 也不行

    5.环境

    这里的环境指的的是<environment id="dev"><environment id="test"> 也是会影响的

        <environments default="dev">
            <environment id="dev">
                <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
                <transactionManager type="JDBC"></transactionManager>
                <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="root"></property>
                </dataSource>
            </environment>
            <environment id="test">
                <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
                <transactionManager type="JDBC"></transactionManager>
                <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="root"></property>
                </dataSource>
            </environment>
        </environments>
    

    总结

  • 相关阅读:
    java:找出占用CPU资源最多的那个线程
    vue中的样式穿透
    宽度过小,左右浮动元素会下沉的解决方案
    Object.keys方法之详解
    element UI实现动态生成多级表头
    JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄
    JavaScript日期格式化处理
    vue点击编辑按钮,内容变成input可以修改,也可以删除
    NProgress颜色的修改以及在Vue中的使用
    vue中使用raphael.js实现地图绘制
  • 原文地址:https://www.cnblogs.com/zhenghengbin/p/13193999.html
Copyright © 2011-2022 走看看