程序员

3.详解MyBatis的配置文件

2017-08-20  本文已影响897人  落叶飞逝的恋

MyBatis配置xml层次结构,而且必须注意其顺序。

<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>

MyBatis官网中文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></properties>
    <!--设置-->
    <settings>
        <setting name="" value=""/>
    </settings>
    <!--类型命名-->
    <typeAliases></typeAliases>
    <!--类型处理器-->
    <typeHandlers></typeHandlers>
    <!--对象工厂-->
    <objectFactory type=""/>
    <!--插件-->
    <plugins>
        <plugin interceptor=""></plugin>
    </plugins>
    <!--配置环境-->
    <environments default="">
        <!--环境变量-->
        <environment id="">
            <!--事务管理器-->
            <transactionManager type=""></transactionManager>
            <!--数据源-->
            <dataSource type="">
            </dataSource>
        </environment>
    </environments>
    <!--数据库厂商标识-->
    <databaseIdProvider type=""/>
    <!--映射器-->
    <mappers></mappers>
</configuration>

1.properties属性

properties是一个配置属性的元素,让我们能在配置文件的上下文中使用它。

如果属性在不止一个地方进行了配置,那么MyBatis按照下面的顺序来加载

因此优先级顺序:方法参数传递的属性 > resource/url 属性中指定的配置文件 > properties 属性中指定的属性

1.1 property子元素

在MyBatis.xml的配置里面配置如下的编码

<dataSource type="pooled">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/springdatastudy?serverTimezone=UTC"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</dataSource>

1.2 properties配置文件

使用properties来配置属性,可以方便我们在多个配置文件重复使用,也可以随时修改及日后维护

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springdatastudy?serverTimezone=UTC
username=root
password=root
<properties resource="datasource.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>

1.3 程序参数传值

实际工作中,数据库的用户名及密码可能是加密后的字符串。所以在SqlSessionFactoryBuilder处,需要将加密的字符串进行解密。

/**
 * 模拟字符串解密
 *
 * @param str
 * @return
 */
public static String decode(String str) {
    return str;
}
public static void main(String[] args) throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    Properties properties = new Properties();
    properties.load(Resources.getResourceAsStream("datasource.properties"));
    properties.setProperty("username",decode(properties.getProperty("username")));
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,properties);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> users = userDao.getUser();
    for (User u : users) {
        System.out.println(u.toString());
    }
}

不要使用混合的方式进行属性配置。优先推荐使用properties文件。

2.settings属性

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。下表描述了设置中各项的意图、默认值等。

boolean属性,默认是true。该配置影响的所有映射器中配置的缓存的全局开关。

boolean属性,默认值是false。延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。

boolean属性,jar版本3.4.1以下是true。3.4.1以上是false。当启用时,任何方法的调用都会加载该对象的所有属性。不开启,按需加载。

boolean属性,默认值是true。是否允许单一语句返回多结果集合。(需要兼容驱动)

boolean属性,默认值为true。使用列标签代替列名。

boolean属性,默认值为false。允许JDBC支持自动生成主键。如果设置为true,则这个设置强制使用自动生成主键。(需要驱动兼容)

枚举属性,三个可选值:None(表示取消自动映射)、Partial(表示只会自动映射没有定义嵌套结果集映射的结果集)、Full(表示会自动映射任意复杂的结果集),默认值为:Partial。

枚举属性,三个可选值:None(不做任何反应)、WARNING(输出提醒日志,org.apache.ibatis.session.AutoMappingUnknownColumnBehavior日志等级必须设置为Warn)、FAILING(映射失败,抛出SqlSessionException)。默认值为None。

枚举属性,三个可选值:SIMPLE(普通执行器)、REUSE(会重用预处理语句(prepared statements))、BATCH(重用语句并执行批量更新)

任意正整数,默认值没有设置。设置超时时间,它决定驱动等待数据库响应的秒数。

任意正整数,默认值没有设置。为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。

boolean属性,默认值为false。允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false。

boolean属性,默认值为true。允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为false。

boolean属性,默认为false。是否开启自动驼峰命名规则(camelcase)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。

枚举属性,两个枚举属性:SESSION(会缓存一个会话中执行的所有查询)、STATEMENT(本地会话仅用在语句执行上,对相同SqlSession的不同调用将不会共享数据。)。默认值为SESSION。

JDBCType属性,常用的属性有:Null、Varchar、Other。当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。

指定哪个对象的方法触发一次延迟加载。

指定动态SQL生成的默认语言。

Specifies the TypeHandler used by default for Enum. (Since: 3.4.5)

boolean属性,默认值为false。。指定当结果集中值为null的时候是否调用映射对象的 setter(map 对象时为put)方法,这对于有Map.keySet()依赖或null值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。

boolean属性,默认值为false。当返回行的所有列都是空时,MyBatis默认返回null。

String类型,指定 MyBatis 增加到日志名称的前缀。

枚举值,指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

枚举值,指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。CGLIB | JAVASSIST。默认值:JAVASSIST (MyBatis 3.3 or above)

指定VFS的实现。自定义VFS的实现的类全限定名,以逗号分隔。

boolean属性,默认值为true。允许使用方法签名中的名称作为语句参数名称。为了使用该特性,你的工程必须采用Java8编译,并且加上-parameters选项。(从3.4.1开始)

指定一个提供Configuration实例的类.这个被返回的Configuration实例是用来加载被反序列化对象的懒加载属性值. 这个类必须包含一个签名方法static Configuration getConfiguration(). (从 3.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(类型别名)

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:

<typeAliases>
    <typeAlias type="model.User" alias="yuser"></typeAlias>
</typeAliases>
<select id="getUser" resultType="yuser">
    select * FROM  user;
</select>

3.1 自动扫描包自定义别名

如果POJO过多的时候,配置也非常多。这时候,我们可以使用自动扫描包自定义别名的方式。

<typeAliases>
    <package name="model"/>
</typeAliases>
@Alias("sasUser")
public class User {
}
<select id="getUser" resultType="sasUser">
    select * FROM  user;
</select>

3.2系统定义别名

别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

4.typeHandlers(类型处理器)

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。

也就是将参数从Java类型(javaType)转换为jdbcType;或者从数据库取出结果把jdbcType转化为javaType。

typeHandler和typeAliases(类型别名)一样,分为系统定义及用户自定义。

4.1 系统定义的typeHandler

类型处理器 Java 类型 JDBC 类型
BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 数据库兼容的字节流类型
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定类型
EnumTypeHandler Enumeration Type VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。

注意点:

DateTime与Timestamp区别

4.2 自定义TypeHanlder

一般情况下,MyBatis系统定义的typeHandler已经应付了大部分场景,但是有时候我们需要特殊处理一些Java类型与JDBC对应的类型,该如何定义。

@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        System.out.println("example setNonNullParameter");
        ps.setString(i,parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        System.out.println("example getNullableResult");
        return rs.getString(columnName);
    }

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

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        System.out.println("example getNullableResult");
        return cs.getString(columnIndex);
    }
}

注释:
使用@MappedTypes注释,来指定与其关联的Java类型列表。
使用@MappedJdbcTypes注释,来指定与其关联的JDBC类型列表

<!--类型处理器-->
<typeHandlers>
    <typeHandler javaType="string" jdbcType="VARCHAR" handler="utils.ExampleTypeHandler"/>
</typeHandlers>

尽管上面我们自定义了类型处理器类,并在MyBatis全局xml里面配置了类型处理器。但是MyBatis还是不会自动启用你定义的typeHandler进行转换结果。需要人为的去指定哪些参数哪些结果类型去用自定义类型处理器。

需要人为配置jdbcType和javaType。或者直接用typeHandler属性指定。

定义jdbcType和javaType

<resultMap id="AllColumnMap" type="model.DateDemo">
    <result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
    <result column="createdOn" property="createOn"/>
</resultMap>

直接使用typeHandler

<resultMap id="AllColumnMap" type="model.DateDemo">
    <result column="name" property="name" javaType="string" jdbcType="VARCHAR" typeHandler="utils.ExampleTypeHandler"/>
    <result column="createdOn" property="createOn"/>
</resultMap>

select语句

<select id="getUser" resultType="model.DateDemo" resultMap="AllColumnMap">
    select * from datedemo;
</select>

4.3 枚举类型的typeHandler

虽然MyBatis提供了两个转化枚举的typeHandler给我们使用,但是对应枚举却有自己的特殊转换要求

public enum Sex {
    MALE(1, "男"),
    FEMALE(2, "女");
    private int id;

    private String name;

    private Sex(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

当只有类用到字段属性Sex时候,才用到枚举类型处理器。一般实际项目中,都是使用int作为枚举类型。这边就跳过介绍。

5. ObjectFactory对象工厂

当MyBatis在构建一个结果返回的时候,都会使用ObjectFactory去构建POJO,在MyBatis中可以定制自己的对象工厂。一般而言使用默认的DefaultObjectFactory。这里不在赘述。

6.environments配置环境

配置环境可以注册多个数据源(dataSource),每一个数据源分为两大部分,一个是数据库源的配置,另一个是数据库事务(transactionManager)的配置。

<!--配置环境-->
<environments default="default">
    <!--环境变量-->
    <environment id="default">
        <!--事务管理器-->
        <transactionManager type="JDBC"></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>

transactionManager配置的是数据库事务。其中type属性有三种配置方式。

dataSource,是配置数据源连接的信息。type属性有4种。

6.1 数据库事务

数据库事务是由SqlSession去控制的,可以通过SqlSession提交(commit)或者回滚(rollback)。如果成功就提交,如果失败就回滚。

try {
    sqlSession.commit();
} catch (Exception ex) {
    ex.printStackTrace();
    sqlSession.rollback();
}

7.mappers(映射器)

上述的一些是MyBatis的一些行为属性配置。那么我们现在要定义SQL映射语句了。但是首先我们需要告诉MyBatis到哪里去找到这些语句。

可以使用类路径的资源引用,或者完全限定的资源定位符(包括:file:///的URL),或者类名和包名。

<mappers>
    <mapper resource="mapper/DateDemoDao.xml"></mapper>
</mappers>
<!-- Register all interfaces in a package as mappers -->
<mappers>
  <package name="org.mybatis.builder"/>
</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>
<!-- 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>
上一篇下一篇

猜你喜欢

热点阅读