Mybatis SQL执行前准备

331 阅读5分钟

Mybatis 相关执行配置

设置相关的Configuration配置信息

     Configuration configuration = new Configuration();
     //设置环境配置
     //通过JdbcTransactionFactory创建jdbc Transaction事务管理器
     //创建DataSource
     Environment environment = new Environment("development", new JdbcTransactionFactory(),
         new UnpooledDataSource("org.***.jdbcDriver", "jdbc:***", "user", "123456"));
     //2. 设置环境信息
     configuration.setEnvironment(environment);
     // 3. 设置是否自增
     configuration.setUseGeneratedKeys(true);
     configuration.addMapper(Mapper.class);
  1. 设置环境变量Environment,也可以通过XML方法配置

     <environments default="development">
       <environment id="development">
       </environment>
     </environments>
    
    • 默认使用的环境 ID(比如:default="development")。
    • 每个 environment 元素定义的环境 ID(比如:id="development")。

    MyBatis可以配置多种环境,简单来说就是可以将 SQL 映射应用于多种数据库。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。

  2. 通过TransactionFactory设置事务管理器,也可以XML方法,如下

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

在 MyBatis 中有两种事务管理器JDBC和MANAGED( type="JDBC/MANAGED")

  • JDBC – 直接使用了 JDBC 提交和回滚功能,它依赖从数据源获得的连接来管理事务作用域。****

  • MANAGED – 让容器来管理事务的整个生命周期。从不提交或回滚一个连接, 默认情况下它会关闭连接。如果一些容器不希望连接被关闭,因此需要将closeConnection属性设置为 false 来阻止默认的关闭行为。例如:

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

这两种事务管理器类型都不需要设置任何属性。用 TransactionFactory 接口实现来代替如JdbcTransactionFactory和ManagedTransactionFactory。

 public interface TransactionFactory {
   default void setProperties(Properties props) { // 从 3.5.2 开始,该方法为默认方法
     // 空实现
   }
   Transaction newTransaction(Connection conn);
   Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
 }

在事务管理器实例化后, XML 中配置的属性将会被传递给 setProperties() 方法。可以通过 Transaction 接口的实现类来实现相关功能,如JdbcTransaction,ManagedTransaction,下发表格展示了JdbcTransaction,ManagedTransaction的特性和区别:

 public interface Transaction {
   Connection getConnection() throws SQLException;
   void commit() throws SQLException;
   void rollback() throws SQLException;
   void close() throws SQLException;
   Integer getTimeout() throws SQLException;
 }
JdbcTransactionManagedTransaction
属性访问权限:protected属性访问权限: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); //设置自动提交 }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. 数据源(dataSource) ,Mybatis3一般有三种数据源类型(UNPOOLED/POOLED/JNDI):

    UNPOOLED– 每次请求都会打开和关闭连接。面向对数据库连接可用性要求不高的程序。 UNPOOLED 类型的数据源需要配置如下:

    • driver – 这是 JDBC 驱动的 Java 类全限定名(并不是 JDBC 驱动中可能包含的数据源类)。
    • url – 这是数据库的 JDBC URL 地址。
    • username – 登录数据库的用户名。
    • password – 登录数据库的密码。
    • defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
    • defaultNetworkTimeout – 等待数据库操作完成的默认网络超时时间(单位:毫秒)。

    POOLED– 支持数据库连接池,避免创建新的连接实例时所必需的初始化和认证时间。 配置 POOLED 数据源的属性:

    • poolMaximumActiveConnections – 最大连接数量,默认值:10
    • poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。(注意:任意时间,默认值5)
    • poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒( 20 秒)
    • poolTimeToWait – 线程等待时间,获取连接超时,连接池会打印状态日志,并重新尝试获取一个连接(避免在误配置的情况下一直失败且不打印日志),默认值:20000 毫秒(即 20 秒)。
    • poolMaximumLocalBadConnectionTolerance – 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程。 如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过 poolMaximumIdleConnectionspoolMaximumLocalBadConnectionTolerance 之和。 默认值:3
    • poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,保证了多数数据库驱动出错时返回适当的错误消息。
    • poolPingEnabled – 是否启用侦测查询。若开启,需要设置 poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。
    • poolPingConnectionsNotUsedFor – poolPingQuery 的频率。可以设置为和数据库连接超时时间一样,避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 仅当 poolPingEnabled 为 true 时适用)。

    JNDI – 在 EJB 或应用服务器等容器中使用,容器可以集中或在外部配置数据源,然后放在 JNDI 上下文引用。配置只需要两个属性:

    • initial_context – 用来在 InitialContext 中寻找上下文(即,initialContext.lookup(initial_context))。是个可选属性,如果忽略,那么将会直接从 InitialContext 中寻找 data_source 属性。
    • data_source – 引用数据源实例位置的上下文路径。提供了 initial_context 配置时,会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。

    可以通过添加前缀“env.”直接把属性传递给 InitialContext。比如:

    • env.encoding=UTF8 // InitialContext 实例化时往它的构造方法传递值为 UTF8encoding 属性

    一般通过DataSourceFactory` 来使用第三方数据源实现:

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

    org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory 可被用作父类来构建新的数据源适配器,比如下面这段插入 C3P0 数据源所必需的代码:

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

    为了令其工作,记得在配置文件中为每个希望 MyBatis 调用的 setter 方法增加对应的属性。 下面是一个可以连接至 PostgreSQL 数据库的例子:

     <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:mybatis.org/mybatis-3/z…

JDBC:juejin.cn/post/700629…