連mybits工作原理都不懂,你敢說你自己會java?

雲棲號資訊:【點擊查看更多行業資訊
在這裏您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!


一、相較於Hibernate,mybatis的優勢在哪裏?

Hibernate缺點:

1、運行效率低,內存佔用比較嚴重
2、針對單一對象的增刪改查,適合Hibernate,而Hibernate在批量操作時處於弱勢
3、雖然Hibernate引入一二級緩存、lazyload、查詢緩存等更多優化空間(對於那些改動 不大且經常使用的數據,可將他們放入緩存中),但Hibernate對於持久層封裝過於完 整,導致開發人員無法對sql進行優化,不適用於大型項目

mybatis優點:

1、代碼量大大減少,開發效率高
2、 MyBatis相當靈活,SQL寫在XML裏,從程序代碼中徹底分離,降低耦合度,便於統 一管理和優化,並可重用
3、運行效率高

二、mybatis原理

下面是mybatis的一個原理圖,看懂這個圖對理解mybatis工作原理很重要:

2

上面的原理圖看的不是很清晰,下面再詳細介紹一下mybatis的主要成員:

1、Configuration

MyBatis所有的配置信息都保存在Configuration對象之中,配置文件的大部分配置都會存儲到該類中

2、SqlSession

作爲MyBatis工作的主要頂層API,表示和數據庫交互時的會話,完成必要數據庫增刪改查功能

3、ExecutorMy

Batis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護

StatementHandler 封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設置參數等

4、ParameterHandler

負責對用戶傳遞的參數轉換成JDBC Statement 所對應的數據類型

5、ResultSetHandler

負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合

6、TypeHandler

負責java數據類型和jdbc數據類型(也可以說是數據表列類型)之間的映射和轉換

7、MappedStatement

MappedStatement維護一條節點的封裝

8、SqlSource

負責根據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,並返回

9、BoundSql

表示動態生成的SQL語句以及相應的參數信息

下面介紹一下mybatis的工作流程:

首先,mybatis的增刪改查這些數據庫操作都是基於sqlsession類的,SqlSession又是由SqlSessionFactory類創建出來的(這裏採用了java設計模式中的工廠模式),而SqlSessionFactory是由SqlSessionFactoryBuilder創建的,SqlSessionFactoryBuilder要想創建SqlSessionFactory,必須要有原料(即mybatis配置文件),下面是創建SqlSession的代碼:

//加載classpath路徑下的mybatis配置文件InputStream in=Resources.getResourceAsStream("mybatis-config.xml");//根據加載配置文件產生的輸入流,來創建一個SqlSessionFactorySqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);//根據SqlSessionFactory創建SqlSessionSqlSession session = sessionFactory.openSession();

下面介紹這幾個重要對象的作用域和生命週期

1、SqlSessionFactoryBuilder

這個類可以被實例化、使用和丟棄,一旦創建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 實例的最佳作用域是方法作用域(也就是局部方法變量)。你可以重用 SqlSessionFactoryBuilder 來創建多個 SqlSessionFactory 實例,但是最好還是不要讓其一直存在以保證所有的 XML 解析資源開放給更重要的事情。

2、SqlSessionFactory

SqlSessionFactory 一旦被創建就應該在應用的運行期間一直存在,沒有任何理由對它進行清除或重建。使用 SqlSessionFactory 的最佳實踐是在應用運行期間不要重複創建多次。因此 SqlSessionFactory 的最佳作用域是應用作用域。有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式

3、SqlSession

每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變量也不行。sqlSession在每次用完之後必須關閉它

三、mybatis緩存機制

1、一級緩存

MyBatis一級緩存是基於sqlSession的,sqlSession對象有一個HashMap用於存儲緩存數據,此HashMap是當前會話對象私有的,別的SqlSession會話對象無法訪問。一級緩存默認是開啓的,且無法關閉。增刪改操作會清空當前sqlSession裏的緩存

2、二級緩存

MyBatis二級緩存是mapper級別的緩存,同一個namespace共用這一個緩存,所以對SqlSession是共享的,二級緩存是默認關閉的。

如何配置二級緩存?只需要在sql映射文件中添加即可

測試代碼:

/* * 注意:被緩存的數據要實現序列化接口(在這裏將Book.java實現序列化接口),否則會出現異常 * 另外,當某一個sqlSession修改了共享的緩存數據之後,二級緩存也會清空 */SqlSession session_1 = MyBatisUtil.getSession();BookDao mapper_1 = session_1.getMapper(BookDao.class);mapper_1.listBook();//注意,必須提交才能將數據放進二級緩存session_1.commit();        SqlSession session_2 = MyBatisUtil.getSession();BookDao mapper_2 = session_2.getMapper(BookDao.class);mapper_2.listBook();

這裏只是爲了測試二級緩存的原理,所以MyBatisUtil類如何獲取SqlSession的代碼就沒有粘貼進來了。

4

運行上面的代碼,通過log4j打印出來的日誌可以看到,,明明運行了兩次listBook方法,但最終查詢語句(select * from book)只出現一次,這次因爲第二次查詢命中了緩存,就不需要再查數據庫了。

【雲棲號在線課堂】每天都有產品技術專家分享!
課程地址:https://yqh.aliyun.com/live

立即加入社羣,與專家面對面,及時瞭解課程最新動態!
【雲棲號在線課堂 社羣】https://c.tb.cn/F3.Z8gvnK

原文發佈時間:2020-07-06
本文作者:程序員麥冬
本文來自:“掘金”,瞭解相關信息可以關注“XXXX”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章