二配置(笔记)

Posted 文nKkCJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二配置(笔记)相关的知识,希望对你有一定的参考价值。

结合springBoot
以及单独使用mybatis来验证一波 ,这几个问题在后面都会进行讲解,先看了文档在说

对象工厂
插件的使用
多环境配置 https://mybatis.org/mybatis-3...
事务处理器

配置文件

configuration(配置)

  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
  • environment(环境变量)
  • transactionManager(事务管理器)
  • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

一、properties(属性)

1、这些属性可以在外部进行配置,并可以进行动态替换。

你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值。比如:

<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

这个例子中的 username 和 password 将会由 properties 元素中设置的相应值来替换。

2、MyBatis 3.4.2 开始,你可以为占位符指定一个默认值。

<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${username:ut_user}"/> <!-- 如果属性 \'username\' 没有被配置,\'username\' 属性的值将为 \'ut_user\' -->
</dataSource>

这个特性默认是关闭的。要启用这个特性,需要添加一个特定的属性来开启这个特性。例如:

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 启用默认值特性 -->
</properties>

3、 修改默认值的分隔符

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 -->
</properties>

结果

<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${db:username?:ut_user}"/>
</dataSource>

二、设置settings

<settings>
  <setting name="cacheEnabled" value="true"/>        #全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认true
  <setting name="lazyLoadingEnabled" value="true"/>    #延迟加载的全局开关特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。
  <setting name="multipleResultSetsEnabled" value="true"/> #是否允许单个语句返回多结果集(需要数据库驱动支持)。
  <setting name="useColumnLabel" value="true"/>        #使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。
  <setting name="useGeneratedKeys" value="false"/>  #允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)
  <setting name="autoMappingBehavior" value="PARTIAL"/> #指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>  #指定发现自动映射目标未知列(或未知属性类型)的行为。 none 不做任何行为(默认)Warning 输出警告日志 failing 映射失败
  <setting name="defaultExecutorType" value="SIMPLE"/>  #配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。
  <setting name="defaultStatementTimeout" value="25"/>    #设置超时时间,它决定数据库驱动等待数据库响应的秒数。
  <setting name="defaultFetchSize" value="100"/>        #为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。
  <setting name="safeRowBoundsEnabled" value="false"/>    #是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 默认false
  <setting name="mapUnderscoreToCamelCase" value="false"/>#是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
  <setting name="localCacheScope" value="SESSION"/>        #MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。
  <setting name="jdbcTypeForNull" value="OTHER"/>        #当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>#指定对象的哪些方法触发一次延迟加载。
</settings> 

三、类别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

四、类型处理器
类型处理器将获取到的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。

自定义类型处理器

// ExampleTypeHandler.java
@MappedJdbcTypes(JdbcType.VARCHAR)   #@MappedTypes注解指定与其关联的 JDBC 类型列表。 如果在 jdbcType 属性中也同时指定,则注解上的配置将被忽略。
public class ExampleTypeHandler extends BaseTypeHandler<String> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getString(columnName);
  }

  @Override
  public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return rs.getString(columnIndex);
  }

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return cs.getString(columnIndex);
  }
}
<!-- mybatis-config.xml -->
<typeHandlers>
  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>

使用上述的类型处理器将会覆盖已有的处理 Java String 类型的属性以及 VARCHAR 类型的参数和结果的类型处理器。 要注意 MyBatis 不会通过检测数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指明字段是 VARCHAR 类型, 以使其能够绑定到正确的类型处理器上。这是因为 MyBatis 直到语句被执行时才清楚数据类型。

在resulMap 映射关系中使用 jdbcType =XX 和javaType = XXX 来显示的指定类型处理器,

配置mybatis来帮你查找类型处理器:注意在使用自动发现功能的时候,只能通过注解方式来指定 JDBC 的类型

<!-- mybatis-config.xml -->
<typeHandlers>
  <package name="org.mybatis.example"/>
</typeHandlers>

五、对象工厂(objectFactory)

每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。比如
// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
  public Object create(Class type) {
    return super.create(type);
  }
  public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
    return super.create(type, constructorArgTypes, constructorArgs);
  }
  public void setProperties(Properties properties) {
    super.setProperties(properties);
  }
  public <T> boolean isCollection(Class<T> type) {
    return Collection.class.isAssignableFrom(type);
  }}
<!-- mybatis-config.xml -->
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
  <property name="someProperty" value="100"/>
</objectFactory>
ObjectFactory 接口很简单,它包含两个创建实例用的方法,一个是处理默认无参构造方法的,另外一个是处理带参数的构造方法的。 另外,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

六、插件(plugins)

除了用插件来修改 MyBatis 核心行为以外,还可以通过完全覆盖配置类来达到目的。只需继承配置类后覆盖其中的某个方法,再把它传递到 SqlSessionFactoryBuilder.build(myConfig) 方法即可。再次重申,这可能会极大影响 MyBatis 的行为,务请慎之又慎

七、环境配置(environments)
环境配置(environments)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);

使用哪种环境就传那种环境
<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

注意一些关键点:

默认使用的环境 ID(比如:default="development") 开发环境。
每个 environment 元素定义的环境 ID(比如:id="development")。
事务管理器的配置(比如:type="JDBC")。
数据源的配置(比如:type="POOLED")。

八、事务管理器(transactionManager)
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):

JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。例如:

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

说明:spring中自带了事务管理器来管理事务

1、事务管理器工厂顶层接口
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 接口的实现类,

2、事务接口
public interface Transaction {
  Connection getConnection() throws SQLException;
  void commit() throws SQLException;
  void rollback() throws SQLException;
  void close() throws SQLException;
  Integer getTimeout() throws SQLException;
}

springBoot中手动事务 、开启事务管理@EnableTransactionManagement

// 需要先注入如下两个类
@Autowired
DataSourceTransactionManager dataSourceTransactionManager;
@Autowired
TransactionDefinition transactionDefinition;

public void saveAll(){
    //开启事务
    TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
    try{
        this.save();
        //提交事务
        dataSourceTransactionManager.commit(transactionStatus);
    }catch(Exception e){
        //回滚事务
        dataSourceTransactionManager.rollback(transactionStatus);
    }
}

九、数据源 (dataSource)
有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]"):

数据库池
<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"/>
//<property name="defaultTransactionIsolationLevel " value="root"/> #连接的事务隔离级别
//<property name="driver.encoding" value="UTF8"/> #连接的事务隔离级别
//<property name="defaultNetworkTimeout " value="10"/> # 等待数据库操作完成的默认网络超时时间(单位:毫秒)

</dataSource>

十、数据库厂商标识(databaseIdProvider)

设置了输出库厂商后,MyBatis 可以根据不同的数据库厂商执行不同的语句,具体是获取了databaseId 后进行判断
<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>
  <property name="Oracle" value="oracle" />
</databaseIdProvider>

顶层接口

public interface DatabaseIdProvider {
  default void setProperties(Properties p) { // 从 3.5.2 开始,该方法为默认方法
    // 空实现
  }
  String getDatabaseId(DataSource dataSource) throws SQLException;
}

十一、映射器(mappers)

以上是关于二配置(笔记)的主要内容,如果未能解决你的问题,请参考以下文章

Alfred常见使用

NLog学习笔记二:深入学习

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段11——vue路由的配置

VSCode自定义代码片段11——vue路由的配置

Spring4学习笔记二:Bean相关