mybatis_user_guide(3)XML配置

来源:互联网 发布:合肥网络推广mdseo 编辑:程序博客网 时间:2024/06/04 18:02
【-1】README
1)本文全文总结于 http://www.mybatis.org/mybatis-3/zh/configuration.html#environments

【0】MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。文档的顶层结构如下:
    - configuration 配置        - properties 属性        - settings 设置        - typeAliases 类型命名        - typeHandlers 类型处理器        - objectFactory 对象工厂        - plugins 插件        - environments 环境            - environment 环境变量                - transactionManager 事务管理器                - dataSource 数据源        - databaseIdProvider 数据库厂商标识        - mappers 映射器
【1】properties 属性
method1)通过属性文件引入属性配置


method2)通过 <properties> 子元素 <property> 动态配置
<properties resource="jdbc.properties">  <property name="username" value="error_root"/> </properties>
method3)通过 方法传递设置
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, props);// ... or ...SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, props);
1)如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:(干货——属性设置的优先级)
1.1)在 properties 元素体内指定的属性首先被读取。
1.2)然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
1.3)最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。

因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的是 properties 属性中指定的属性。

【2】setting
1)intro: 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
2)下表描述了设置中各项的意图、默认值等:
3)一个配置完整的 settings 元素的示例如下:
<settings>  <setting name="cacheEnabled" value="true"/>  <setting name="lazyLoadingEnabled" value="true"/>  <setting name="multipleResultSetsEnabled" value="true"/>  <setting name="useColumnLabel" value="true"/>  <setting name="useGeneratedKeys" value="false"/>  <setting name="autoMappingBehavior" value="PARTIAL"/>  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>  <setting name="defaultExecutorType" value="SIMPLE"/>  <setting name="defaultStatementTimeout" value="25"/>  <setting name="defaultFetchSize" value="100"/>  <setting name="safeRowBoundsEnabled" value="false"/>  <setting name="mapUnderscoreToCamelCase" value="false"/>  <setting name="localCacheScope" value="SESSION"/>  <setting name="jdbcTypeForNull" value="OTHER"/>  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings>
【3】typeAliases
1)intro:类型别名是为 Java 类型设置一个短的名,就是取个别名;
2)取别名
<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>
当这样配置时,Blog可以用在任何使用domain.blog.Blog的地方。

3)也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
<typeAliases>  <package name="domain.blog"/></typeAliases>
supplement)每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。看下面的例子:

4)已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理。



【4】类型处理器
1)intro:无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。


2)你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。比如:
// ExampleTypeHandler.java@MappedJdbcTypes(JdbcType.VARCHAR)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 在 mybatis的配置文件 xml 中 引用该类型处理器--><typeHandlers>  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/></typeHandlers>
3) 最后,可以让 MyBatis 为你查找类型处理器:
<!-- mybatis-config.xml --><typeHandlers>  <package name="org.mybatis.example"/></typeHandlers>
Attention)注意在使用自动检索(autodiscovery)功能的时候,只能通过注解方式来指定 JDBC 的类型。

【5】处理枚举类型(EnumTypeHandler  EnumOrdinalTypeHandler)
1)intro:若想映射枚举类型 Enum,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选一个来使用。
Attention)注意 EnumTypeHandler 在某种意义上来说是比较特别的,其他的处理器只针对某个特定的类,而它不同,它会处理任意继承了 Enum 的类。

2)看个荔枝:比如说我们想存储取近似值时用到的舍入模式。
2.1)默认情况下:MyBatis 会利用 EnumTypeHandler 来把 Enum 值转换成对应的名字。
2.2)不过,我们可能不想存储名字,相反我们的 DBA 会坚持使用整形值代码: 在配置文件中把 EnumOrdinalTypeHandler 加到 typeHandlers 中即可, 这样每个 RoundingMode 将通过他们的序数值来映射成对应的整形;
<!-- mybatis-config.xml --><typeHandlers>  <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="java.math.RoundingMode"/></typeHandlers>

2)problem+solution:
2.1)problem:但是怎样能将同样的 Enum 既映射成字符串又映射成整形呢?

2.2)solution:自动映射器(auto-mapper)会自动地选用 EnumOrdinalTypeHandler 来处理, 所以如果我们想用普通的 EnumTypeHandler,就非要为那些 SQL 语句显式地设置要用到的类型处理器不可。


【6】objectFactory 对象工厂
1)intro:MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 
2)自定义对象工厂: 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。比如:
// ExampleObjectFactory.javapublic 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="setProperties" value="100"/></objectFactory>
对以上代码的分析(Analysis): ObjectFactory 接口很简单,它包含两个创建用的方法,一个是处理默认构造方法的,另外一个是处理带参数的构造方法的。 最后,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

【7】 plugins 插件
1)intro: MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。
2)默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:    
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)    - ParameterHandler (getParameterObject, setParameters)    - ResultSetHandler (handleResultSets, handleOutputParameters)    - StatementHandler (prepare, parameterize, batch, update, query)
Attention) 因为如果在试图修改或重写已有方法的行为的时候,你很可能在破坏 MyBatis 的核心模块。 这些都是更低层的类和方法,所以使用插件的时候要特别当心。(干货——使用插件的时候要特别当心

2)如何使用插件?只需实现 Interceptor 接口,并指定了想要拦截的方法签名即可。
// ExamplePlugin.java@Intercepts({@Signature(  type= Executor.class,  method = "update",  args = {MappedStatement.class,Object.class})})public class ExamplePlugin implements Interceptor {  public Object intercept(Invocation invocation) throws Throwable {    return invocation.proceed();  }  public Object plugin(Object target) {    return Plugin.wrap(target, this);  }  public void setProperties(Properties properties) {  }}
<!-- mybatis-config.xml --><plugins>  <plugin interceptor="org.mybatis.example.ExamplePlugin">    <property name="setProperties" value="100"/>  </plugin></plugins>
对以上代码的分析(Analysis): 上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行低层映射语句的内部对象。

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

【7】environments  环境
1)可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。 所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单;
2)每个数据库对应一个 SqlSessionFactory 实例: 为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。可以接受环境配置的两个方法签名是:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);
2.1) 如果忽略了环境参数,那么默认环境将会被加载,如下所示:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);
2.2)环境元素定义了如何配置环境。
<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”)。保证默认环境要匹配其中一个环境ID。(干货——即是说,必要要配置默认环境==development)

【7.1】transactionManager 事务管理器
1)intro: 在 MyBatis 中有两种类型的事务管理器(也就是 type=”[JDBC|MANAGED]”):
type1)JDBC : 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。(干货——可以直接使用回滚和提交的设置)
type2)MANAGED: 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。例如:
<transactionManager type="MANAGED">  <property name="closeConnection" value="false"/></transactionManager>
Attention) 如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。

2)这两种事务管理器类型都不需要任何属性。它们不过是类型别名,换句话说,你可以使用 TransactionFactory 接口的实现类的完全限定名或类型别名代替它们。
public interface TransactionFactory {  void setProperties(Properties props);    Transaction newTransaction(Connection conn);  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);  }

3)任何在 XML 中配置的属性在实例化之后将会被传递给 setProperties() 方法。你也需要创建一个 Transaction 接口的实现类,这个接口也很简单:
public interface Transaction {  Connection getConnection() throws SQLException;  void commit() throws SQLException;  void rollback() throws SQLException;  void close() throws SQLException;  Integer getTimeout() throws SQLException;}
Attention)使用这两个接口,你可以完全自定义 MyBatis 对事务的处理。(干货——通过实现 TransactionFactory 和 Transaction 接口 可以自定义 MyBatis 对事务的处理,即设置回滚和是否自动提交)

【7.2】dataSource 数据源
1)intro: 有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”):

【7.2.1】UNPOOL 类型的数据源
1)intro: 这个数据源的实现只是每次被请求时打开和关闭连接;
2)UNPOOLED 类型的数据源仅仅需要配置以下 5 种属性:
property1)driver: 这是 JDBC 驱动的 Java 类的完全限定名(并不是JDBC驱动中可能包含的数据源类)。
property2)url这是数据库的 JDBC URL 地址。
property3)username登录数据库的用户名。
property4)password登录数据库的密码。
property5)defaultTransactionIsolationLevel默认的连接事务隔离级别。

Supplement)作为可选项,你也可以传递属性给数据库驱动。要这样做,属性的前缀为“driver.”,例如:driver.encoding=UTF8;这将通过DriverManager.getConnection(url,driverProperties)方法传递值为 UTF8 的 encoding 属性给数据库驱动。


【7.2.2】POOLED类型的数据源
1)intro: 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。 
2)除了上述提到 UNPOOLED 下的属性外,会有更多属性用来配置 POOLED 的数据源:
    - poolMaximumActiveConnections – 在任意时间可以存在的活动(也就是正在使用)连接数量,默认值:10    - poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。    - poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)    - poolTimeToWait – 这是一个底层设置,如果获取连接花费的相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静的失败),默认值:20000 毫秒(即 20 秒)。    - poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否处在正常工作秩序中并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。    - poolPingEnabled – 是否启用侦测查询。若开启,也必须使用一个可执行的 SQL 语句设置 poolPingQuery 属性(最好是一个非常快的 SQL),默认值:false。    - poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的使用频度。这可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。

【7.2.3】JNDI类型的数据源:
1)intro: 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用;
2)这种数据源配置只需要两个属性:
    - initial_context – 这个属性用来在 InitialContext 中寻找上下文(即,initialContext.lookup(initial_context))。这是个可选属性,如果忽略,那么 data_source 属性将会直接从 InitialContext 中寻找。    - data_source – 这是引用数据源实例位置的上下文的路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。
3)和其他数据源配置类似,可以通过添加前缀“env.”直接把属性传递给初始上下文。比如: env.encoding=UTF8 ,这就会在初始上下文(InitialContext)实例化时往它的构造方法传递值为 UTF8  encoding 属性;

4)通过需要实现接口 org.apache.ibatis.datasource.DataSourceFactory , 也可使用任何第三方数据源,:

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

5) 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();  }}

6) 为了令其工作,为每个需要 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>

【8】 databaseIdProvider 数据库厂商标识
1)intro: MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 
2)为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:
<databaseIdProvider type="DB_VENDOR" />
3)这里的 DB_VENDOR 会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置。 由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短,如下:
<databaseIdProvider type="DB_VENDOR">  <property name="SQL Server" value="sqlserver"/>  <property name="DB2" value="db2"/>          <property name="Oracle" value="oracle" /></databaseIdProvider>

【9】 mappers 映射器
1)intro: 既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。 你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:
<!-- Using classpath relative resources --><mappers>  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>  <mapper resource="org/mybatis/builder/PostMapper.xml"/></mappers>
<!-- Using url fully qualified paths --><mappers>  <mapper url="file:///var/mappers/AuthorMapper.xml"/>  <mapper url="file:///var/mappers/BlogMapper.xml"/>  <mapper url="file:///var/mappers/PostMapper.xml"/></mappers>
<!-- Using mapper interface classes --><mappers>  <mapper class="org.mybatis.builder.AuthorMapper"/>  <mapper class="org.mybatis.builder.BlogMapper"/>  <mapper class="org.mybatis.builder.PostMapper"/></mappers>
<!-- Register all interfaces in a package as mappers --><mappers>  <package name="org.mybatis.builder"/></mappers>

Attention)这些配置会告诉了 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件了,也就是接下来我们要讨论的。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝不喜欢奶粉的味道怎么办 四个月宝宝不喜欢吃奶粉怎么办 四岁宝宝有口臭怎么办 4个月宝宝口臭怎么办 2岁宝宝有口臭是怎么办 两岁宝宝有口气怎么办 2岁宝宝口气重是什么原因怎么办 两岁宝宝口气重怎么办 两岁宝宝有口臭怎么办 两岁身高不达标怎么办 两岁宝宝82厘米怎么办 2岁幼儿说话结巴怎么办 2岁的宝宝结巴怎么办 2岁半宝宝口吃怎么办 2周岁宝宝不说话怎么办 三周岁宝宝不说话怎么办 2周岁宝宝突然说话结巴怎么办 两周岁宝宝突然说话结巴怎么办 三周岁宝宝说话突然结巴怎么办 小孩g和d不分怎么办 两岁宝宝皮肤黑怎么办 2岁宝宝肤色偏黄怎么办 2岁宝宝迷上手机怎么办 2岁宝宝说话口吃怎么办 两岁宝宝突然口吃怎么办 两岁半的宝宝还不会说话怎么办 2岁宝宝自闭症怎么办呀 新生儿又吐又拉怎么办 一岁多宝宝受凉呕吐拉稀怎么办 7个月的宝宝腹泻怎么办 两岁宝宝拉稀水怎么办 2岁宝宝发烧呕吐怎么办 1岁宝宝着凉呕吐怎么办 2岁着凉了呕吐怎么办 2岁宝宝着凉呕吐怎么办 两岁宝宝偏矮怎么办 2岁宝贝吐没精神怎么办 11个月的宝宝吐怎么办 二岁的宝宝吐了怎么办 十个月小孩吐了怎么办 10个月宝宝呕吐怎么办