首頁 > Java > java教程 > 什麼是查詢快取? MyBatis查詢快取的用法介紹

什麼是查詢快取? MyBatis查詢快取的用法介紹

零下一度
發布: 2017-06-25 10:56:07
原創
2389 人瀏覽過

轉載請註明出處: 

前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(七)-MyBatis延遲載入

1.什麼是查詢快取

mybatis提供查詢緩存,用於減輕資料庫壓力,提高資料庫效能。

mybatis提供一級快取和二級快取。

一級快取是SqlSession層級的快取。在操作資料庫時需要建構sqlSession對象,在對像中有一個資料結構(HashMap)用來儲存快取資料。不同的sqlSession之間的快取資料區域(HashMap)是互相不影響的。

二級快取是mapper層級的緩存,多個sqlSession去操作同一個Mapper的sql語句,多個sqlSession可以共用二級緩存,二級快取是跨sqlSession的。

為什麼要用快取?

如果快取中有資料就不用從資料庫中獲取,大大提高系統效能。

2.一級快取

2.1一級快取工作原理

# 第一次發起查詢用戶id為1的用戶信息,先去找快取中是否有id為1的使用者信息,如果沒有,從資料庫查詢使用者資訊。

得到使用者訊息,將使用者資訊儲存到一級快取。

如果sqlSession去執行commit操作(執行插入、更新、刪除),清空sqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免髒讀。

第二次發送查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。

 2.2一級快取測試

 mybatis預設支援一級緩存,不需要在設定檔去設定。

 依照上邊一級快取原理步驟去測試。

    @Testpublic void testCache1() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//下边查询使用一个SqlSession//第一次发起请求,查询id为1的用户User user1=userMapper.findUserById(1);
        System.out.println(user1);        //如果sqlSession去执行commit操作(执行插入、更新、删除),清空sqlSession中的一级缓存,//这样做的目的是为了让缓存中存储的是最新的信息,避免脏读。//更新user1的信息user1.setUsername("测试用户22");
        userMapper.updateUser(user1);//执行commit操作去清空缓存        sqlSession.commit();        //第二次发起请求,查询id为1的用户User user2=userMapper.findUserById(1);
        System.out.println(user2);

        sqlSession.close();
    }
登入後複製

2.3一級快取應用

 正式開發,是將mybatis和spring進行整合開發,事務控制在service中。

一個service方法中包含很多Mapper方法呼叫。

service{

  //開始執行時,開啟事務,建立SqlSession物件

  //第一次呼叫mapper的方法findUserById(1)

 

  //第二次呼叫mapper的方法findUserById(1),從一級快取中取資料

  //方法結束,sqlSession關閉

#}

  //方法結束,sqlSession關閉

#}

  //方法結束,sqlSession關閉

#}

如果是執行兩次service呼叫查詢相同的使用者信息,不走一級緩存,因為session方法結束,sqlSession就關閉,一級快取就清空。

3.二級快取

3.1二級快取原則

#首先開啟mybatis的二級快取。

sqlSession1去查詢用戶id為1的用戶訊息,查詢到用戶資訊後悔講查詢資料儲存到二級快取。

如果sqlSession3去執行相同mapper下的sql,執行commit提交,會清空該mapper下的二級快取區域的資料。

sqlSession2去查詢用戶id為1的用戶信息,去緩存找是否存在數據,如果存在直接從緩存中取出數據。

二級快取與一級快取區別:二級快取的範圍更大,多個sqlSession可以共享一個UserMapper的二級快取區域。 UserMapper有一個二級快取區域(按namespace分),它mapper也有自己的二級快取區域(按namespace分)。

每個namespace的mapper都有一個二級快取區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到的資料將存在相同的二級快取區域中。

3.2開啟二級快取
mybatis的二級快取是mapper範圍級別,除了在SqlMapConfig.xml設定二級快取的總開關,還要在特定的mapper.xml中開啟二級緩存。 在核心設定檔SqlMapConfig.xml中加入:
<setting name="cacheEnabled" value="true"/>
登入後複製
## 

描述

允許值
預設值

#cacheEnabled

對在此設定檔下的所有cache 進行全域性開/關設定。

true false
true###############

在UserMapper.xml中开启二级缓存,UserMapper.xml下的sql执行完成后存储在它的缓存区域(HashMap)。

3.3调用pojo类实现序列化接口

为了将缓存数据取出执行反序列划操作,因为二级缓存数据存储介质多种多样,不一定在内存。可能在硬盘、远程等。

3.4测试方法

    @Testpublic void testCache2() throws Exception{
        SqlSession sqlSession1=sqlSessionFactory.openSession();
        SqlSession sqlSession2=sqlSessionFactory.openSession();
        SqlSession sqlSession3=sqlSessionFactory.openSession();
        
        UserMapper userMapper1=sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2=sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3=sqlSession3.getMapper(UserMapper.class);        //第一次发起请求,查询id为1的用户User user1=userMapper1.findUserById(1);
        System.out.println(user1);//这里执行关闭操作,将sqlSession中的数据写到二级缓存区域        sqlSession1.close();        //使用sqlSession3执行commit()操作User user=userMapper3.findUserById(1);
        user1.setUsername("Joanna");
        userMapper3.updateUser(user);//执行提交,清空UserMapper下边的二级缓存        sqlSession3.commit();
        sqlSession3.close();        //第二次发起请求,查询id为1的用户User user2=userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();
    }
登入後複製

3.5禁用二级缓存

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql,默认情况是true,即该sql使用二级缓存。