Sqlsession 的理解


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的工廠.

 

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塊來關閉它.

 1 //SqlSession接口源碼如下所示:
 2 
 3 package org.apache.ibatis.session;
 4 
 5 import java.io.Closeable;
 6 import java.sql.Connection;
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 import org.apache.ibatis.executor.BatchResult;
11 
12 public interface SqlSession extends Closeable {
13 
14   <T> T selectOne(String statement);
15 
16   <T> T selectOne(String statement, Object parameter);
17 
18   <E> List<E> selectList(String statement);
19 
20   <E> List<E> selectList(String statement, Object parameter);
21 
22   <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
23 
24   <K, V> Map<K, V> selectMap(String statement, String mapKey);
25 
26   <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
27 
28   <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
29 
30   void select(String statement, Object parameter, ResultHandler handler);
31 
32   void select(String statement, ResultHandler handler);
33 
34   void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
35 
36   int insert(String statement);
37 
38   int insert(String statement, Object parameter);
39 
40   int update(String statement);
41 
42   int update(String statement, Object parameter);
43 
44   int delete(String statement);
45 
46   int delete(String statement, Object parameter);
47 
48   void commit();
49 
50   void commit(boolean force);
51 
52   void rollback();
53 
54   void rollback(boolean force);
55 
56   List<BatchResult> flushStatements();
57 
58   void close();
59 
60   void clearCache();
61 
62   Configuration getConfiguration();
63 
64   <T> T getMapper(Class<T> type);
65 
66   Connection getConnection();
67 }

三、SqlSessionFactory和SqlSession實現過程

 

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單獨的配置文件. 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

 3 3 <configuration>  4 4  5 5 <!-- 加載數據庫屬性文件 -->  6 6 <properties resource="jdbc.properties">  7 7 </properties>  8 8 <!-- 可以配置多個運行環境,但是每個 SqlSessionFactory 實例只能選擇一個運行環境 一、development:開發模式 二、work:工作模式 -->  9 9 <environments default="development"> 10 10 <!--id屬性必須和上面的default一樣 --> 11 11 <environment id="development"> 12 12 <transactionManager type="JDBC" /> 13 13 <!--dataSource 元素使用標准的 JDBC 數據源接口來配置 JDBC 連接對象源 --> 14 14 <dataSource type="POOLED"> 15 15 <property name="driver" value="${jdbc.driver}" /> 16 16 <property name="url" value="${jdbc.url}" /> 17 17 <property name="username" value="${jdbc.username}" /> 18 18 <property name="password" value="${jdbc.password}" /> 19 19 </dataSource> 20 20 </environment> 21 21 </environments> 22 22 <!-- 在配置文件中 關聯包下的 接口類-->
23 23 <mappers> 24 24 <mapper resource="com/ys/mapper/userMapper.xml"/> 25 25 </mappers> 26 26 </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兩個對象給一個具體的使用過程:
*/
1
package com.cn.testIUserService; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import org.apache.ibatis.io.Resources; 6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 9 10 import com.cn.entity.User; 11 12 public class MyBatisTest { 13 14 public static void main(String[] args) { 15 try { 16 //讀取mybatis-config.xml文件 17 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); 18 //初始化mybatis,創建SqlSessionFactory類的實例 19 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); 20 //創建session實例 21 SqlSession session = sqlSessionFactory.openSession(); 22 /* 23 * 接下來在這里做很多事情,到目前為止,目的已經達到得到了SqlSession對象.通過調用SqlSession里面的方法, 24 * 可以測試MyBatis和Dao層接口方法之間的正確性,當然也可以做別的很多事情,在這里就不列舉了 25 */ 26 //插入數據 27 User user = new User(); 28 user.setC_password("123"); 29 user.setC_username("123"); 30 user.setC_salt("123"); 31 //第一個參數為方法的完全限定名:位置信息+映射文件當中的id 32 session.insert("com.cn.dao.UserMapping.insertUserInformation", user); 33 //提交事務 34 session.commit(); 35 //關閉session 36 session.close(); 37 } catch (IOException e) { 38 e.printStackTrace(); 39 } 40 } 41 }
結合上述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對象了。
得到SqlSession對象之后就可以利用SqlSession內部的方法進行CRUD操作了。

注意一點,Connection對象是在SqlSession對象創建之后進行CURD操作中創建的。深入查找之后找到在ManagedTransaction類中找到獲取Connection對象的關鍵代碼如下:

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { 2 Transaction tx = null; 3 try { 4 //通過Confuguration對象去獲取Mybatis相關配置信息, Environment對象包含了數據源和事務的配置 5 // execType為執行器類型,配置文件中定義 6 // SimpleExecutor -- SIMPLE 就是普通的執行器。 7 //ReuseExecutor -執行器會重用預處理語句(prepared statements) 8 //BatchExecutor --它是批量執行器 9 final Environment environment = configuration.getEnvironment(); 10 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); 11 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); 12 //定義執行器,是對statement的封裝 13 final Executor executor = configuration.newExecutor(tx, execType); 14 //最后返回一個SqlSession 15 return new DefaultSqlSession(configuration, executor, autoCommit); 16 } catch (Exception e) { 17 closeTransaction(tx); // may have fetched a connection so lets call close() 18 throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); 19 } finally { 20 ErrorContext.instance().reset(); 21 } 22 }
 1   protected void openConnection() throws SQLException {
 2     if (log.isDebugEnabled()) {
 3       log.debug("Opening JDBC Connection");
 4     }
 5     //dataSource 來源有三種,JndiDatasource,PooledDataSource,UnpooledDataSource,配置文件中定義
 6     this.connection = this.dataSource.getConnection();
 7     if (this.level != null) {
 8       this.connection.setTransactionIsolation(this.level.getLevel());
 9     }
10   }

PooledDataSource和UnPooledDataSource的區別是PooledDataSource使用了連接池。為什么使用連接池呢?因為創建一個Connection對象的過程,在底層就相當於和數據庫建立的通信連接,在建立通信連接的過程,消耗了非常多的時間,而往往我們建立連接后(即創建Connection對象后),就執行一個簡單的SQL語句,然后就要拋棄掉,這是一個非常大的資源浪費!mybatis針對這一個問題提出的PooledDataSource使用了連接池

--------------------- 

作者:可樂丶 

來源:CSDN 

原文:https://blog.csdn.net/u013412772/article/details/73648537 

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

前言:學習框架一個比較好的路徑閱讀源碼.本文介紹的SqlSessionFactory和SqlSession.可以通過了解SqlSessionFactory接口和SqlSession接口以及兩個的實現類入手,去看源碼了解實現過程.最好能把項目下載到本地,慢慢分析實現過程.
Myabtis官網:http://www.mybatis.org/ github地址:https://github.com/mybatis/mybatis-3


MyBatis的持久化解決方案是將用戶從原始的JDBC訪問中解放出來,用戶只需要定義需要操作的SQL語句,無須關注底層的JDBC操作,就可以以面向對象的方式來進行持久化層操作.底層數據庫連接的獲取,數據訪問的實現,事務控制等都無須用戶關心,從而將應用層從底層的JDBC/JTA API抽取出來.通過配置文件管理JDBC連接,讓MyBatis解決持久化的實現.在MyBatis中的常見對象有SqlSessionFactory和SqlSession.本文這種介紹一下兩者的概念和使用.
一、 SqlSessionFactorySqlSessionFactory是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();
}12345678910111213141516171819202122二、SqlSessionSqlSession是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();}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768三、SqlSessionFactory和SqlSession實現過程mybatis框架主要是圍繞着SqlSessionFactory進行的,創建過程大概如下:
(1)、定義一個Configuration對象,其中包含數據源、事務、mapper文件資源以及影響數據庫行為屬性設置settings
(2)、通過配置對象,則可以創建一個SqlSessionFactoryBuilder對象
(3)、通過 SqlSessionFactoryBuilder 獲得SqlSessionFactory 的實例。
(4)、SqlSessionFactory 的實例可以獲得操作數據的SqlSession實例,通過這個實例對數據庫進行操作1234567並且如果想按照上述方式得到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>  123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051下面的這行代碼功能是通過配置文件mybatis-config.xml,創建SqlSessionFactory對象,然后產生SqlSession,執行SQL語句.而mybatis的初始化發生在:
SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(resourceAsStream);12如果是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>12345關於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();        }    }}1234567891011121314151617181920212223242526272829303132333435363738394041針對上面的代碼給出詳細的說明關於SqlSessionFactory和SqlSession創建過程涉及的內容.


結合上述SqlSessionFactory和SqlSession使用過程和結構圖,涉及到的方法為下面步驟,結合源碼中的方法為下面的步驟:
第一步首先SqlSessionFactoryBuilder去讀取mybatis的配置文件,然后build一個DefaultSqlSessionFactory,即得到SqlSessionFactory1//源碼中涉及的包和具體方法為://涉及的包為: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;  }123456789101112131415161718192021222324252627282930313233343536第二步,獲取到SqlSessionFactory之后,就可以利用SqlSessionFactory方法的openSession來獲取SqlSession對象了。1private 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();  }}12345678910111213141516171819202122得到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());    }  }12345678910PooledDataSource和UnPooledDataSource的區別是PooledDataSource使用了連接池。為什么使用連接池呢?因為創建一個Connection對象的過程,在底層就相當於和數據庫建立的通信連接,在建立通信連接的過程,消耗了非常多的時間,而往往我們建立連接后(即創建Connection對象后),就執行一個簡單的SQL語句,然后就要拋棄掉,這是一個非常大的資源浪費!mybatis針對這一個問題提出的PooledDataSource使用了連接池。--------------------- 作者:可樂丶 來源:CSDN 原文:https://blog.csdn.net/u013412772/article/details/73648537 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM