Mybatis SQL執(zhí)行前準(zhǔn)備

Mybatis 相關(guān)執(zhí)行配置

設(shè)置相關(guān)的Configuration配置信息

    Configuration configuration = new Configuration();
    //設(shè)置環(huán)境配置
    //通過(guò)JdbcTransactionFactory創(chuàng)建jdbc Transaction事務(wù)管理器
    //創(chuàng)建DataSource
    Environment environment = new Environment("development", new JdbcTransactionFactory(),
        new UnpooledDataSource("org.***.jdbcDriver", "jdbc:***", "user", "123456"));
    //2. 設(shè)置環(huán)境信息
    configuration.setEnvironment(environment);
    // 3. 設(shè)置是否自增
    configuration.setUseGeneratedKeys(true);
    configuration.addMapper(Mapper.class);
  1. 設(shè)置環(huán)境變量Environment,也可以通過(guò)XML方法配置

    <environments default="development">
      <environment id="development">
      </environment>
    </environments>
    
    • 默認(rèn)使用的環(huán)境 ID(比如:default="development")。
    • 每個(gè) environment 元素定義的環(huán)境 ID(比如:id="development")。

    MyBatis可以配置多種環(huán)境,簡(jiǎn)單來(lái)說(shuō)就是可以將 SQL 映射應(yīng)用于多種數(shù)據(jù)庫(kù)。例如,開(kāi)發(fā)、測(cè)試和生產(chǎn)環(huán)境需要有不同的配置;或者想在具有相同 Schema 的多個(gè)生產(chǎn)數(shù)據(jù)庫(kù)中使用相同的 SQL 映射。

  2. 通過(guò)TransactionFactory設(shè)置事務(wù)管理器,也可以XML方法,如下

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    </environment>
</environments>

在 MyBatis 中有兩種事務(wù)管理器JDBC和MANAGED( type="JDBC/MANAGED")

  • JDBC – 直接使用了 JDBC 提交和回滾功能,它依賴(lài)從數(shù)據(jù)源獲得的連接來(lái)管理事務(wù)作用域。 ****

  • MANAGED – 讓容器來(lái)管理事務(wù)的整個(gè)生命周期。從不提交或回滾一個(gè)連接, 默認(rèn)情況下它會(huì)關(guān)閉連接。如果一些容器不希望連接被關(guān)閉,因此需要將closeConnection屬性設(shè)置為 false 來(lái)阻止默認(rèn)的關(guān)閉行為。例如:

    <transactionManager type="MANAGED">
      <property name="closeConnection" value="false"/>
    </transactionManager>
    

這兩種事務(wù)管理器類(lèi)型都不需要設(shè)置任何屬性。用 TransactionFactory 接口實(shí)現(xiàn)來(lái)代替如JdbcTransactionFactory和ManagedTransactionFactory。

public interface TransactionFactory {
  default void setProperties(Properties props) { // 從 3.5.2 開(kāi)始,該方法為默認(rèn)方法
    // 空實(shí)現(xiàn)
  }
  Transaction newTransaction(Connection conn);
  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}

在事務(wù)管理器實(shí)例化后, XML 中配置的屬性將會(huì)被傳遞給 setProperties() 方法??梢酝ㄟ^(guò) Transaction 接口的實(shí)現(xiàn)類(lèi)來(lái)實(shí)現(xiàn)相關(guān)功能,如JdbcTransaction,ManagedTransaction,下發(fā)表格展示了JdbcTransaction,ManagedTransaction的特性和區(qū)別:

public interface Transaction {
  Connection getConnection() throws SQLException;
  void commit() throws SQLException;
  void rollback() throws SQLException;
  void close() throws SQLException;
  Integer getTimeout() throws SQLException;
}
JdbcTransaction ManagedTransaction
屬性訪問(wèn)權(quán)限:protected 屬性訪問(wèn)權(quán)限:private
public void commit() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + connection + "]");
}
connection.commit();
}
}
public void commit() throws SQLException {
// Does nothing
}
public void rollback() throws SQLException {
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Rolling back JDBC Connection [" + connection + "]");
}
connection.rollback();
}
}
public void rollback() throws SQLException {
// Does nothing
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
connection = dataSource.getConnection();
if (level != null) {
connection.setTransactionIsolation(level.getLevel());
}
**setDesiredAutoCommit(autoCommit); **//設(shè)置自動(dòng)提交
}
protected void openConnection() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("Opening JDBC Connection");
}
this.connection = this.dataSource.getConnection();
if (this.level != null) {
this.connection.setTransactionIsolation(this.level.getLevel());
}
}
public void close() throws SQLException {
if (connection != null) {
resetAutoCommit();
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + connection + "]");
}
connection.close();
}
}
public void close() throws SQLException {
if (this.closeConnection && this.connection != null) {
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
  1. 數(shù)據(jù)源(dataSource),Mybatis3一般有三種數(shù)據(jù)源類(lèi)型(UNPOOLED/POOLED/JNDI):

    UNPOOLED– 每次請(qǐng)求都會(huì)打開(kāi)和關(guān)閉連接。面向?qū)?shù)據(jù)庫(kù)連接可用性要求不高的程序。 UNPOOLED 類(lèi)型的數(shù)據(jù)源需要配置如下:

    • driver – 這是 JDBC 驅(qū)動(dòng)的 Java 類(lèi)全限定名(并不是 JDBC 驅(qū)動(dòng)中可能包含的數(shù)據(jù)源類(lèi))。
    • url – 這是數(shù)據(jù)庫(kù)的 JDBC URL 地址。
    • username – 登錄數(shù)據(jù)庫(kù)的用戶名。
    • password – 登錄數(shù)據(jù)庫(kù)的密碼。
    • defaultTransactionIsolationLevel – 默認(rèn)的連接事務(wù)隔離級(jí)別。
    • defaultNetworkTimeout – 等待數(shù)據(jù)庫(kù)操作完成的默認(rèn)網(wǎng)絡(luò)超時(shí)時(shí)間(單位:毫秒)。

    POOLED– 支持?jǐn)?shù)據(jù)庫(kù)連接池,避免創(chuàng)建新的連接實(shí)例時(shí)所必需的初始化和認(rèn)證時(shí)間。 配置 POOLED 數(shù)據(jù)源的屬性:

    • poolMaximumActiveConnections – 最大連接數(shù)量,默認(rèn)值:10
    • poolMaximumIdleConnections – 任意時(shí)間可能存在的空閑連接數(shù)。(注意:任意時(shí)間,默認(rèn)值5)
    • poolMaximumCheckoutTime – 在被強(qiáng)制返回之前,池中連接被檢出(checked out)時(shí)間,默認(rèn)值:20000 毫秒( 20 秒)
    • poolTimeToWait – 線程等待時(shí)間,獲取連接超時(shí),連接池會(huì)打印狀態(tài)日志,并重新嘗試獲取一個(gè)連接(避免在誤配置的情況下一直失敗且不打印日志),默認(rèn)值:20000 毫秒(即 20 秒)。
    • poolMaximumLocalBadConnectionTolerance – 這是一個(gè)關(guān)于壞連接容忍度的底層設(shè)置, 作用于每一個(gè)嘗試從緩存池獲取連接的線程。 如果這個(gè)線程獲取到的是一個(gè)壞的連接,那么這個(gè)數(shù)據(jù)源允許這個(gè)線程嘗試重新獲取一個(gè)新的連接,但是這個(gè)重新嘗試的次數(shù)不應(yīng)該超過(guò) poolMaximumIdleConnectionspoolMaximumLocalBadConnectionTolerance 之和。 默認(rèn)值:3
    • poolPingQuery – 發(fā)送到數(shù)據(jù)庫(kù)的偵測(cè)查詢(xún),用來(lái)檢驗(yàn)連接是否正常工作并準(zhǔn)備接受請(qǐng)求。默認(rèn)是“NO PING QUERY SET”,保證了多數(shù)數(shù)據(jù)庫(kù)驅(qū)動(dòng)出錯(cuò)時(shí)返回適當(dāng)?shù)腻e(cuò)誤消息。
    • poolPingEnabled – 是否啟用偵測(cè)查詢(xún)。若開(kāi)啟,需要設(shè)置 poolPingQuery 屬性為一個(gè)可執(zhí)行的 SQL 語(yǔ)句(最好是一個(gè)速度非??斓?SQL 語(yǔ)句),默認(rèn)值:false。
    • poolPingConnectionsNotUsedFor – poolPingQuery 的頻率??梢栽O(shè)置為和數(shù)據(jù)庫(kù)連接超時(shí)時(shí)間一樣,避免不必要的偵測(cè),默認(rèn)值:0(即所有連接每一時(shí)刻都被偵測(cè) — 僅當(dāng) poolPingEnabled 為 true 時(shí)適用)。

    JNDI – 在 EJB 或應(yīng)用服務(wù)器等容器中使用,容器可以集中或在外部配置數(shù)據(jù)源,然后放在 JNDI 上下文引用。配置只需要兩個(gè)屬性:

    • initial_context – 用來(lái)在 InitialContext 中尋找上下文(即,initialContext.lookup(initial_context))。是個(gè)可選屬性,如果忽略,那么將會(huì)直接從 InitialContext 中尋找 data_source 屬性。
    • data_source – 引用數(shù)據(jù)源實(shí)例位置的上下文路徑。提供了 initial_context 配置時(shí),會(huì)在其返回的上下文中進(jìn)行查找,沒(méi)有提供時(shí)則直接在 InitialContext 中查找。

    可以通過(guò)添加前綴“env.”直接把屬性傳遞給 InitialContext。比如:

    • env.encoding=UTF8 // InitialContext 實(shí)例化時(shí)往它的構(gòu)造方法傳遞值為 UTF8encoding 屬性

    一般通過(guò)DataSourceFactory` 來(lái)使用第三方數(shù)據(jù)源實(shí)現(xiàn):

    public interface DataSourceFactory {
      void setProperties(Properties props);
      DataSource getDataSource();
    }
    

    org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory 可被用作父類(lèi)來(lái)構(gòu)建新的數(shù)據(jù)源適配器,比如下面這段插入 C3P0 數(shù)據(jù)源所必需的代碼:

    import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {
    
      public C3P0DataSourceFactory() {
        this.dataSource = new ComboPooledDataSource();
      }
    }
    

    為了令其工作,記得在配置文件中為每個(gè)希望 MyBatis 調(diào)用的 setter 方法增加對(duì)應(yīng)的屬性。 下面是一個(gè)可以連接至 PostgreSQL 數(shù)據(jù)庫(kù)的例子:

    <dataSource type="org.myproject.C3P0DataSourceFactory">
      <property name="driver" value="org.postgresql.Driver"/>
      <property name="url" value="jdbc:postgresql:mydb"/>
      <property name="username" value="postgres"/>
      <property name="password" value="root"/>
    </dataSource>
    

參考資料

mybatis中文api:https://mybatis.org/mybatis-3/zh/configuration.html

JDBC:http://www.itdecent.cn/p/1635f4bda51b

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容