MyBatis入門 核心物件
XML 配置檔案或 Configuration 類的例項 --> SqlSessionFactoryBuilder --build()--> SqlSessionFactory --openSession()--> SqlSession (執行已對映的 SQL 語句)
每個 MyBatis 的應用程式都以一個 SqlSessionFactory 物件的例項為核心,SqlSessionFactory物件例項可以通過 SqlSessionFactoryBuilder 物件來獲得。首先獲取 SqlSessionFactoryBuilder 物件,可以根據 XML 配置檔案或 Configuration 類的例項構建該物件。然後獲取 SqlSessionFactory 物件,有了 SqlSessionFactory 物件之後,就可以進而獲取 Sqlsession 例項, Sqlsession 物件中完全包含以資料庫為背景的所有執行 SQL 操作的方法。可以用該例項來直接執行已對映的 SQL 語句。
SqlSessionFactoryBuilder
1、SqlSessionFactoryBuilder 作用
SqlSessionFactoryBuilder 負責構建 SqlSessionFactory,並且提供了多個 build() 方法的過載,由於方法引數 environment 和 Properties 都可以為 null,那麼去除重複的,真正的過載方法其實只有如下三種:
1 2 3 |
build(Reader reader,String environment,Properties properties)
build(InputStream inputStream,String environment,Properties properties) build(Configuration config)
|
通過上述分析,發現配置資訊可以以三種形式提供給 SqlSessionFactoryBuilder 的 build() 方法,分別是 InputStream(位元組流)、 Reader(字元流)、 Configuration(類),由於位元組流與字元流都屬於讀取配置檔案的方式,所以從配置資訊的來源就很容易想到構建一個 SqlSessionFactory 有兩種方式:讀取 XML 配置檔案構造方式和程式設計構造方式。
2、SqlSessionFactoryBuilder 的生命週期和作用域
SqlSessionFactoryBuilder 的最大特點是:用過即丟。一旦建立了 SqlSessionFactory 物件之後,這個類就不再需要存在了,因此 SqlSessionFactoryBuilder 的最佳範圍就是存在於方法體內,也就是區域性變數而已。即最佳範圍是方法範圍 (本地方法變數)。
SqlSessionFactory
1、SqlSessionFactory 的作用
SqlSessionFactory 簡單的理解就是建立 SqlSession 例項的工廠。所有的 MyBatis 應用都是以 SqlSessionFactory 例項為中心, SqlSessionFactory 的例項可以通過 SqlSessionFactoryBuilder 物件來獲得。有了它之後,就可以通過 SqlSessionFactory 提供的 openSession() 方法來獲取 SqlSession 例項。
說明: openSession() 方法的引數為 boolean 值時,若傳入 true 表示關閉事務控制,自動提交; false 表示開啟事務控制。若不傳入引數,預設為 true。
1 2 |
openSession ( boolean autoCommit)
openSession() //若不傳入引數,預設為 true ,自動提交
|
2、SqlSessionFactory 的生命週期和作用域
SqlSessionFactory 物件一旦建立,就會在整個應用執行過程中始終存在。沒有理由去銷燬或再建立它,並且在應用執行中也不建議多次建立 SqlSessionFactory 。因此 SqlSessionFactory 的最佳作用域是 Application,即隨著應用的生命週期一同存在。那麼這種 “存在於整個應用執行期間,並且同時只存在一個物件例項” 的模式就是所謂的單例模式(指在應用執行期間有且僅有一個例項)。即 SqlSessionFactory 的最佳範圍是應用範圍。
SQLSession
1、SqlSession
SqlSession 是用於執行持久化操作的物件,類似於 JDBC 中的 Connection 。它提供了面向資料庫執行 SQL 命令所需的所有方法,可以通過 SqlSession 例項直接執行已對映的 SQL 語句。
2、SqlSession 的生命週期和作用域
正如其名, SqlSession 對應著一次資料庫會話。由於資料庫會話不是永久的,因此 SqlSession 的生命週期也不應該是永久的。相反,在每次訪問資料庫時都需要建立它(注意:並不是說在 SqlSession 裡只能執行一次 SQL,是完全可以執行多次的,但是若關閉了 SqlSession ,那麼就需要重新建立它)。建立 SqlSession 的地方只有一個,那就是 SqlSessionFactory 物件的 openSession()方法。
需要注意的是:每個執行緒都有自己的 SqlSession 例項, SqlSession 例項不能被共享,也不是執行緒安全的。因此最佳的作用域範圍是請求 request 範圍或者方法範圍。
關閉 SqlSession 是非常重要的。必須要確保 SqlSession 在 finally 語句塊中正常關閉。可以使用下面的標準方式來關閉:
SqlSession session =sqlSessionFactory.openSession();
try{
//do work
}finally{
session.close(); //關閉 SqlSession
}
3、SqlSession 的兩種使用方式
//方式 1:通過 SQLSession 例項呼叫 selectList、selectOne 等方法來直接執行已對映的 SQL 語句。(不需要編寫 DAO 介面) // MyBatis 通過 mapper 檔案的 namespace 和子元素的 id 來找到相應的 SQL,從而執行查詢操作 userList=sqlSession.selectList("com.abcabc.dao.UserMapper.getUserList"); //說明: //1、com.abcabc.dao.UserMapper.getUserList=namespace+id //2、使用方式一可以不用寫介面中的方法,因為方式一直接執行對映檔案的 SQL 語句。 //3、執行 CRUD 操作,有引數傳遞時此方式不適用,應使用方式 2。 //方式 2:基於 mapper 介面方式操作資料。(官方推薦使用) //建立繫結對映語句的介面 UserMapper.java,並提供介面方法 getUserList(),該介面稱為對映器。 userList=sqlSession.getMapper(UserMapper.class).getUserList(); //說明: //1、介面的方法必須與 SQL 對映檔案中 SQL 語句的 id 一一對應。 //2、第二種方式是通過 SQLSession 例項呼叫 getMapper(Mapper.class) 執行 Mapper 介面方法來實現對資料庫的查詢操作。 //3、第一種方式是舊版本的 MyBatis 提供的操作方式,雖然現在也可以正常工作,但是第二種方式是 MyBatis 官方所推薦使用的, // 其表達方式也更加直白。程式碼更加清晰,型別安全,也不用擔心易錯的字串字面值以及強制型別轉換。 複製程式碼
獲取 SqlSession 的工具類(MyBatisUtil.java)
此 MyBatisUtil.java 檔案是優化後獲取 SqlSession ,關閉 SqlSession 的公用工具類。
package cn.mybatis.util; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil { private static SqlSessionFactory sessionFactory; static{//在靜態程式碼塊下,sessionFactory 只會被建立一次 try { //讀取 mybatis-config.xml 檔案 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); //建立SqlSessionFactoryBuilder物件 SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder(); //利用SqlSessionFactoryBuilder物件 去構建sessionFactory工廠 sessionFactory = sessionFactoryBuilder.build(in); } catch (IOException e) { e.printStackTrace(); } } //建立sqlSession public static SqlSession getSqlSession(){ //利用sessionFactory工廠物件去生產sqlSession SqlSession sqlSession = sessionFactory.openSession(false);//false代表不會自動提交事務,true 代表自動提交事務 return sqlSession; } //關閉sqlSession public static void close(SqlSession sqlSession){ if(sqlSession!=null){ sqlSession.close(); } } }
REF
https://www.cnblogs.com/wxdestiny/p/9743686.html
https://www.cnblogs.com/yanguobin/p/11711705.html
https://blog.csdn.net/qq_38269362/article/details/108680176