您好,登錄后才能下訂單哦!
這篇文章給大家介紹SqlSessionFactory和SqlSession怎么在MyBatis中使用,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
MyBatis的持久化解決方案是將用戶從原始的JDBC訪問中解放出來,用戶只需要定義需要操作的SQL語句,無須關注底層的JDBC操作,就可以以面向對象的方式來進行持久化層操作.底層數據庫連接的獲取,數據訪問的實現,事務控制等都無須用戶關心,從而將應用層從底層的JDBC/JTA API抽取出來.通過配置文件管理JDBC連接,讓MyBatis解決持久化的實現.在MyBatis中的常見對象有SqlSessionFactory和SqlSession.本文這種介紹一下兩者的概念和使用.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
一、 SqlSessionFactory
SqlSessionFactory是MyBatis的關鍵對象,它是個單個數據庫映射關系經過編譯后的內存鏡像.SqlSessionFactory對象的實例可以通過SqlSessionFactoryBuilder對象類獲得,而SqlSessionFactoryBuilder則可以從XML配置文件或一個預先定制的Configuration的實例構建出SqlSessionFactory的實例.每一個MyBatis的應用程序都以一個SqlSessionFactory對象的實例為核心.同時SqlSessionFactory也是線程安全的,SqlSessionFactory一旦被創建,應該在應用執行期間都存在.在應用運行期間不要重復創建多次,建議使用單例模式.SqlSessionFactory是創建SqlSession的工廠.
//SqlSessionFactory接口源碼如下所示: package org.apache.ibatis.session; import java.sql.Connection; public interface SqlSessionFactory { SqlSession openSession();//這個方法最經常用,用來創建SqlSession對象. SqlSession openSession(boolean autoCommit); SqlSession openSession(Connection connection); SqlSession openSession(TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType); SqlSession openSession(ExecutorType execType, boolean autoCommit); SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType, Connection connection); Configuration getConfiguration(); }
二、SqlSession
SqlSession是MyBatis的關鍵對象,是執行持久化操作的獨享,類似于JDBC中的Connection.它是應用程序與持久層之間執行交互操作的一個單線程對象,也是MyBatis執行持久化操作的關鍵對象.SqlSession對象完全包含以數據庫為背景的所有執行SQL操作的方法,它的底層封裝了JDBC連接,可以用SqlSession實例來直接執行被映射的SQL語句.每個線程都應該有它自己的SqlSession實例.SqlSession的實例不能被共享,同時SqlSession也是線程不安全的,絕對不能講SqlSeesion實例的引用放在一個類的靜態字段甚至是實例字段中.也絕不能將SqlSession實例的引用放在任何類型的管理范圍中,比如Servlet當中的HttpSession對象中.使用完SqlSeesion之后關閉Session很重要,應該確保使用finally塊來關閉它.
//SqlSession接口源碼如下所示: package org.apache.ibatis.session; import java.io.Closeable; import java.sql.Connection; import java.util.List; import java.util.Map; import org.apache.ibatis.executor.BatchResult; public interface SqlSession extends Closeable { <T> T selectOne(String statement); <T> T selectOne(String statement, Object parameter); <E> List<E> selectList(String statement); <E> List<E> selectList(String statement, Object parameter); <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds); <K, V> Map<K, V> selectMap(String statement, String mapKey); <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey); <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds); void select(String statement, Object parameter, ResultHandler handler); void select(String statement, ResultHandler handler); void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler); int insert(String statement); int insert(String statement, Object parameter); int update(String statement); int update(String statement, Object parameter); int delete(String statement); int delete(String statement, Object parameter); void commit(); void commit(boolean force); void rollback(); void rollback(boolean force); List<BatchResult> flushStatements(); void close(); void clearCache(); Configuration getConfiguration(); <T> T getMapper(Class<T> type); Connection getConnection(); }
mybatis框架主要是圍繞著SqlSessionFactory進行的,創建過程大概如下:
(1)、定義一個Configuration對象,其中包含數據源、事務、mapper文件資源以及影響數據庫行為屬性設置settings
(2)、通過配置對象,則可以創建一個SqlSessionFactoryBuilder對象
(3)、通過 SqlSessionFactoryBuilder 獲得SqlSessionFactory 的實例。
(4)、SqlSessionFactory 的實例可以獲得操作數據的SqlSession實例,通過這個實例對數據庫進行操作
并且如果想按照上述方式得到SqlSessionFactory,最好使用下面的mybatis-config.xml類似的配置.在這里mybatis-config.xml配置文件是沒有和Spring配置文件整合過得,如果項目中mybaits的配置文件和Spring配置文件整合過了,則下面的代碼運行估計會出錯,因為一般spring和mybatis整合過之后,mybatis的配置文件基本沒有存在的必要了,之前在mybatis中配置的數據源和事務這兩個方面,一般的做法都會spring的配置文件,則下面的代碼加載mybatis-config.xml的時候,得不到必要的信息,創建的過程中會有問題.所以在這里先給一份mybatis-config.xml單獨的配置文件.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 加載類路徑下的屬性文件 --> <properties resource="db.properties"/> <!-- 設置類型別名 --> <typeAliases> <typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/> </typeAliases> <!-- 設置一個默認的連接環境信息 --> <environments default="mysql_developer"> <!-- 連接環境信息,取一個任意唯一的名字 --> <environment id="mysql_developer"> <!-- mybatis使用jdbc事務管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用連接池方式來獲取連接 --> <dataSource type="pooled"> <!-- 配置與數據庫交互的4個必要屬性 --> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> <!-- 連接環境信息,取一個任意唯一的名字 --> <environment id="oracle_developer"> <!-- mybatis使用jdbc事務管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用連接池方式來獲取連接 --> <dataSource type="pooled"> <!-- 配置與數據庫交互的4個必要屬性 --> <property name="driver" value="${oracle.driver}"/> <property name="url" value="${oracle.url}"/> <property name="username" value="${oracle.username}"/> <property name="password" value="${oracle.password}"/> </dataSource> </environment> </environments> <!-- 加載映射文件--> <mappers> <mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/> </mappers> </configuration>
下面的這行代碼功能是通過配置文件mybatis-config.xml,創建SqlSessionFactory對象,然后產生SqlSession,執行SQL語句.而mybatis的初始化發生在:
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
如果是spring和mybaits整合之后的配置文件,一般以這種方式實現,SqlSessionFactory的創建:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 自動掃描mapping.xml文件 --> <property name="mapperLocations" value="classpath:com/cn/mapper/*.xml"></property> </bean>
關于SqlSessionFactory和SqlSession兩個對象給一個具體的使用過程:
package com.cn.testIUserService; 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; import com.cn.entity.User; public class MyBatisTest { public static void main(String[] args) { try { //讀取mybatis-config.xml文件 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); //初始化mybatis,創建SqlSessionFactory類的實例 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); //創建session實例 SqlSession session = sqlSessionFactory.openSession(); /* * 接下來在這里做很多事情,到目前為止,目的已經達到得到了SqlSession對象.通過調用SqlSession里面的方法, * 可以測試MyBatis和Dao層接口方法之間的正確性,當然也可以做別的很多事情,在這里就不列舉了 */ //插入數據 User user = new User(); user.setC_password("123"); user.setC_username("123"); user.setC_salt("123"); //第一個參數為方法的完全限定名:位置信息+映射文件當中的id session.insert("com.cn.dao.UserMapping.insertUserInformation", user); //提交事務 session.commit(); //關閉session session.close(); } catch (IOException e) { e.printStackTrace(); } } }
針對上面的代碼給出詳細的說明關于SqlSessionFactory和SqlSession創建過程涉及的內容.
結合上述SqlSessionFactory和SqlSession使用過程和結構圖,涉及到的方法為下面步驟,結合源碼中的方法為下面的步驟:
第一步首先SqlSessionFactoryBuilder去讀取mybatis的配置文件,然后build一個DefaultSqlSessionFactory,即得到SqlSessionFactory
//源碼中涉及的包和具體方法為: //涉及的包為:package org.apache.ibatis.session; //第一個類為:SqlSessionFactoryBuilder,設計到此類的方法為下面部分: public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); } public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { //通過XMLConfigBuilder解析配置文件,解析的配置相關信息都會封裝為一個Configuration對象 XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); //然后返回一個DefaultSqlSessionFactory return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } //得到DefaultSqlSessionFactory public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); } //第二個類為:DefaultSqlSessionFactory,涉及的方法為: public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; }
第二步,獲取到SqlSessionFactory之后,就可以利用SqlSessionFactory方法的openSession來獲取SqlSession對象了。
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { //通過Confuguration對象去獲取Mybatis相關配置信息, Environment對象包含了數據源和事務的配置 // execType為執行器類型,配置文件中定義 // SimpleExecutor -- SIMPLE 就是普通的執行器。 //ReuseExecutor -執行器會重用預處理語句(prepared statements) //BatchExecutor --它是批量執行器 final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //定義執行器,是對statement的封裝 final Executor executor = configuration.newExecutor(tx, execType); //最后返回一個SqlSession return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
得到SqlSession對象之后就可以利用SqlSession內部的方法進行CRUD操作了。
注意一點,Connection對象是在SqlSession對象創建之后進行CURD操作中創建的。深入查找之后找到在ManagedTransaction類中找到獲取Connection對象的關鍵代碼如下:
protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Opening JDBC Connection"); } //dataSource 來源有三種,JndiDatasource,PooledDataSource,UnpooledDataSource,配置文件中定義 this.connection = this.dataSource.getConnection(); if (this.level != null) { this.connection.setTransactionIsolation(this.level.getLevel()); } }
PooledDataSource和UnPooledDataSource的區別是PooledDataSource使用了連接池。為什么使用連接池呢?因為創建一個Connection對象的過程,在底層就相當于和數據庫建立的通信連接,在建立通信連接的過程,消耗了非常多的時間,而往往我們建立連接后(即創建Connection對象后),就執行一個簡單的SQL語句,然后就要拋棄掉,這是一個非常大的資源浪費!mybatis針對這一個問題提出的PooledDataSource使用了連接池。關于數據庫連接池的知識點,可以自行百度,在這里就不擴展介紹了.
關于SqlSessionFactory和SqlSession怎么在MyBatis中使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。