Mybatis是如何操做數據庫的
Mybatis操做數據庫,能夠分爲如下五個步驟:sql
- 讀取核心配置文件,生成Configuration對象。
- 根據Configuration對象,經過SqlSessionFactoryBuilder,建立SqlSessionFactory工廠對象。
- 使用SqlSessionFactory工廠對象,獲取SqlSession實例,SqlSession實例提供了API用於操做數據庫。
- Mybatis中使用了JDK動態代理,根據Mapper接口和編寫的sql語句,SqlSession實例生成Mapper代理對象。編寫的sql,會經過註解或者xml的形式,映射到Mapper對象上的方法。
- 執行Mapper的方法時,Mapper中的方法會調用SqlSession實例的方法,SqlSession實例的方法會調用Executor對象,由Executor對象實際去執行數據庫操做,對執行結果封裝等。
Mybatis Executor分類
Executor有如下幾種:數據庫
- BaseExecutor(執行器抽象類),維護一級緩存、管理事務等,對數據的增刪改查,則是調用下面3個執行器的(doQuery、doUpdate)方法來完成。
- SimpleExecutor(簡單執行器),每次執行SQL須要預編譯SQL語句,生成新的預處理器(PreparedStatement)。
- ReuseExecutor(可重用執行器),同一SQL語句執行只須要預編譯一次SQL語句,但屢次調用,仍是會查詢屢次數據庫的
- BatchExecutor(批處理執行器),只針對修改操做的SQL語句預編譯一次,而且須要手動提交修改才生效。
- CachingExecutor(二級緩存的緩存執行器),它是對BaseExecutor的一個包裝,進一步說,也就是對SimpleExecutor、ReuseExecutor、BatchExecutor進行包裝。用於管理二級緩存,而具體的對數據的操做,則是會調用BaseExecutor,由BaseExecutor來完成。
說說Mybatis緩存
Mybatis中會對數據進行緩存。若是同時開啓Mybatis的一二級緩存,查詢時,會先從二級緩存中查詢,若是查詢不到,在一級緩存中查詢,若是還查詢不到,纔到數據庫中查詢。緩存
一級緩存
- 一級緩存是會話級的緩存,即在同個線程屢次查詢同一條數據時,除了第一次,其他次查詢都能再也不操做數據庫,而從緩存中獲取數據。
- 若是修改了數據,不須要提交修改,在同個線程就能查到同一條修改的數據。
- 若是修改、添加、刪除數據,而且進行commit操做提交了,則緩存會清空。
- Mybatis中一級緩存默認打開的。
- 同一個會話中,在知足如下幾個條件時,才能命中緩存,不然仍是會去查數據庫。
- 需知足如下運行時要求:
- 在同一個會話中
- sql語句與參數相同
- 相同的statementId
- RowBounds(分頁)相同
- 需知足如下配置與操做要求:
- 未手動清空緩存 (提交、回滾)
- 未配置flushCache=true
- 未執行update
- 緩存的做用域不是statement,即做用域不是單次數據庫操做
二級緩存
- 二級緩存也稱爲應用級緩存,它的做用範圍是整個應用,便可以跨線程使用。
- 二級緩存適用於一些修改比較少的數據。
- 二級緩存在Mybatis默認不開啓。
- 當某某個SqlSession實例執行修改、添加、刪除數據,而且進行commit操做提交了。則緩存會清空。
- 二級緩存數據,默認使用自帶的PerpetualCache保存在內存和硬盤中,也能夠與第三方集成。
- 二級緩存是基於Mapper級別的,每一個Mapper都有本身的二級緩存區域,按照namespace來劃分,不一樣namespace下的操做互不影響。若是兩個Mapper的namespace相同,則共享同個二級緩存區。
- 在知足如下幾個運行時條件時,才能命中二級緩存。
- sql語句與參數相同
- 相同的statementId
- RowBounds(分頁)相同
Spring整合Mybatis後,Mybatis一級緩存失效?
其實不是失效,而是因爲在未開啓事務的狀況下,在同個線程中,每次查詢後Spring都會關閉舊的sqlSession,須要再次查詢時再建立新的sqlSession。 不是同個sqlSession,天然不會命中一級緩存。app
在開啓事物的狀況之下,Spring會使用threadLocal,把當前線程與一個sqlSession實例綁定,重用該sqlSession實例,所以此時一級緩存是有效的。ide