關於Mybatis的那些小事

關於Mybatis的那些小事

Mybatis是如何操做數據庫的

Mybatis操做數據庫,能夠分爲如下五個步驟:sql

  1. 讀取核心配置文件,生成Configuration對象。
  2. 根據Configuration對象,經過SqlSessionFactoryBuilder,建立SqlSessionFactory工廠對象。
  3. 使用SqlSessionFactory工廠對象,獲取SqlSession實例,SqlSession實例提供了API用於操做數據庫。
  4. Mybatis中使用了JDK動態代理,根據Mapper接口和編寫的sql語句,SqlSession實例生成Mapper代理對象。編寫的sql,會經過註解或者xml的形式,映射到Mapper對象上的方法。
  5. 執行Mapper的方法時,Mapper中的方法會調用SqlSession實例的方法,SqlSession實例的方法會調用Executor對象,由Executor對象實際去執行數據庫操做,對執行結果封裝等。

Mybatis Executor分類

eb8455115a58beacfb9448876b35f595.png

Executor有如下幾種:數據庫

  1. BaseExecutor(執行器抽象類),維護一級緩存、管理事務等,對數據的增刪改查,則是調用下面3個執行器的(doQuery、doUpdate)方法來完成。
  2. SimpleExecutor(簡單執行器),每次執行SQL須要預編譯SQL語句,生成新的預處理器(PreparedStatement)。
  3. ReuseExecutor(可重用執行器),同一SQL語句執行只須要預編譯一次SQL語句,但屢次調用,仍是會查詢屢次數據庫的
  4. BatchExecutor(批處理執行器),只針對修改操做的SQL語句預編譯一次,而且須要手動提交修改才生效。
  5. CachingExecutor(二級緩存的緩存執行器),它是對BaseExecutor的一個包裝,進一步說,也就是對SimpleExecutor、ReuseExecutor、BatchExecutor進行包裝。用於管理二級緩存,而具體的對數據的操做,則是會調用BaseExecutor,由BaseExecutor來完成。

說說Mybatis緩存

Mybatis中會對數據進行緩存。若是同時開啓Mybatis的一二級緩存,查詢時,會先從二級緩存中查詢,若是查詢不到,在一級緩存中查詢,若是還查詢不到,纔到數據庫中查詢。緩存

ba5f55e1c4d260fa4e440b32de5126aa.png

一級緩存

  1. 一級緩存是會話級的緩存,即在同個線程屢次查詢同一條數據時,除了第一次,其他次查詢都能再也不操做數據庫,而從緩存中獲取數據。
  2. 若是修改了數據,不須要提交修改,在同個線程就能查到同一條修改的數據。
  3. 若是修改、添加、刪除數據,而且進行commit操做提交了,則緩存會清空。
  4. Mybatis中一級緩存默認打開的。
  5. 同一個會話中,在知足如下幾個條件時,才能命中緩存,不然仍是會去查數據庫。
  • 需知足如下運行時要求:
    • 在同一個會話中
    • sql語句與參數相同
    • 相同的statementId
    • RowBounds(分頁)相同
  • 需知足如下配置與操做要求:
    • 未手動清空緩存 (提交、回滾)
    • 未配置flushCache=true
    • 未執行update
    • 緩存的做用域不是statement,即做用域不是單次數據庫操做

二級緩存

  1. 二級緩存也稱爲應用級緩存,它的做用範圍是整個應用,便可以跨線程使用。
  2. 二級緩存適用於一些修改比較少的數據。
  3. 二級緩存在Mybatis默認不開啓。
  4. 當某某個SqlSession實例執行修改、添加、刪除數據,而且進行commit操做提交了。則緩存會清空。
  5. 二級緩存數據,默認使用自帶的PerpetualCache保存在內存和硬盤中,也能夠與第三方集成。
  6. 二級緩存是基於Mapper級別的,每一個Mapper都有本身的二級緩存區域,按照namespace來劃分,不一樣namespace下的操做互不影響。若是兩個Mapper的namespace相同,則共享同個二級緩存區。
  7. 在知足如下幾個運行時條件時,才能命中二級緩存。
  • sql語句與參數相同
  • 相同的statementId
  • RowBounds(分頁)相同

Spring整合Mybatis後,Mybatis一級緩存失效?

其實不是失效,而是因爲在未開啓事務的狀況下,在同個線程中,每次查詢後Spring都會關閉舊的sqlSession,須要再次查詢時再建立新的sqlSession。 不是同個sqlSession,天然不會命中一級緩存。app

在開啓事物的狀況之下,Spring會使用threadLocal,把當前線程與一個sqlSession實例綁定,重用該sqlSession實例,所以此時一級緩存是有效的。ide

相關文章
相關標籤/搜索