1. 程式人生 > 實用技巧 >Spring全家桶相關

Spring全家桶相關

1.mybatis工作原理
一、相較於Hibernate,mybatis的優勢在哪裡?
Hibernate缺點:

1、執行效率低,記憶體佔用比較嚴重

2、針對單一物件的增刪改查,適合Hibernate,而Hibernate在批量操作時處於弱勢

3、雖然Hibernate引入一二級快取、lazyload、查詢快取等更多優化空間(對於那些改動 不大且經常使用的資料,可將他們放入快取中),但Hibernate對於持久層封裝過於完 整,導致開發人員無法對sql進行優化,不適用於大型專案

mybatis優點:

1、程式碼量大大減少,開發效率高

2、 MyBatis相當靈活,SQL寫在XML裡,從程式程式碼中徹底分離,降低耦合度,便於統 一管理和優化,並可重用

3、執行效率高

二、mybatis原理
下面是mybatis的一個原理圖,看懂這個圖對理解mybatis工作原理很重要:
在這裡插入圖片描述
上面的原理圖看的不是很清晰,下面再詳細介紹一下mybatis的主要成員:

1、Configuration

MyBatis所有的配置資訊都儲存在Configuration物件之中,配置檔案的大部分配置都會儲存到該類中

2、SqlSession(工廠模式創建出來)

作為MyBatis工作的主要頂層API,表示和資料庫互動時的會話,完成必要資料庫增刪改查功能

3、Executor

MyBatis執行器,是MyBatis 排程的核心,負責SQL語句的生成和查詢快取的維護

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

4、ParameterHandler

負責對使用者傳遞的引數轉換成JDBC Statement 所對應的資料型別

5、ResultSetHandler

負責將JDBC返回的ResultSet結果集物件轉換成List型別的集合

6、TypeHandler

負責java資料型別和jdbc資料型別(也可以說是資料表列型別)之間的對映和轉換

7、MappedStatement

MappedStatement維護一條<select|update|delete|insert>節點的封裝

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”);
//根據載入配置檔案產生的輸入流,來建立一個SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//根據SqlSessionFactory建立SqlSession
SqlSession 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的程式碼就沒有貼上進來了。

Mybatis快取參考
https://www.cnblogs.com/happyflyingpig/p/7739749.html