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>

總結

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

您可能也會喜歡…