MyBatis 全局配置文件

参考

1. 配置顺序

configuration(配置顺序)

2. 属性(properties)

2.1. 定义属性

<properties> 内部可以通过 <propertie> 定义key/value,然后通过${var} 来引用属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<properties>
<!-- 定义属性 -->
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/test?useSSL=true"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 通过${var}来引用 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url"
value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>

2.2. 引用外部配置文件

外部配置文件 jdbc.properties 的内容如下:

1
2
3
4
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=true
jdbc.username=root
jdbc.password=123456

<properties>resource 属性 可以引用classpath下的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<properties resource="jdbc.properties" />

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url"
value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>

<properties>url 属性 可以引用网络中的配置文件,包括本地磁盘中的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<properties url="file:///c:/jdbc.properties" />

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url"
value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>

引用外部配置文件,和直接定义属性,二者可以结合起来。配置加载顺序遵循就近原则。先加载外部,再加载内部。若有冲突,则内部会覆盖外部同名配置

1
2
3
4
5
6
7
8
<!-- resource引用配置文件 -->
<properties resource="file1.properties">
<!-- 直接定义属性 -->
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/test?useSSL=true"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>

3. 设置(settings)

settings 是MyBatis中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

详细说明可以参考官方文档 http://www.mybatis.org/mybatis-3/zh/configuration.html#settings ,下面列举一些常用的配置

3.1. mapUnderscoreToCamelCase

凡是使用Mybatis,一般都要设置mapUnderscoreToCamelCase为true

1
2
3
4
5
6
<!-- mapUnderscoreToCamelCase
描述:是否开启自动驼峰命名规则(camel case)映射,
即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射
有效值:true | false
默认值:false -->
<setting name="mapUnderscoreToCamelCase" value="true"/>

4. 类型别名(typeAliases)

typeAliases可以给Java数据类型起一个别名,存在的意义仅在于用来减少类完全限定名的冗余

但是在实际开发中,不推荐使用typeAliases,而是推荐直接使用全类名。使用全类名的好处是,你可以很清晰地看出,这个类型属于哪个包。而且使用全类名,在IDE中,可以通过CTRL+左键直接定位到对应的类,便于查看

4.1. typeAlias起别名

1
2
3
4
5
<typeAliases>
<!-- 省略alias属性时,别名默认就是简单类名,例如demo.mybatis.entity.Person的别名默认就是Person -->
<typeAlias type="demo.mybatis.entity.Person" />
<typeAlias type="demo.mybatis.entity.Car" alias="car" />
</typeAliases>

在SQL映射文件中,都可以用别名替代全类名

1
2
3
4
<!-- resultType的值本来要写"demo.mybatis.entity.Person",现在就可以用别名简写了 -->
<select id="findById" resultType="Person">
SELECT * FROM person WHERE person_id = #{personId}
</select>

需要注意的是,别名的使用是不区分大小写的。例如你给demo.mybatis.entity.Person设置别名为person,引用别名时,Person、perSON等等都是等价的

1
2
3
4
<!-- 使用PERSON也是可以的 -->
<select id="findById" resultType="PERSON">
SELECT * FROM person WHERE person_id = #{personId}
</select>

4.2. package批量起别名

假如有很多个类,你都想起别名,一个一个设置别名就会很累,此时可以使用<package>,mybatis会自动扫描该包及其子包(递归扫描)所有的类,将简单类名作为别名。

需要注意,这里的别名仍是不区分大小写的

1
2
3
4
5
6
7
<typeAliases>
<!--
demo.entity.Person ==> Person
demo.entity.aaa.bbb.Car ==> Car
-->
<package name="demo.entity" />
</typeAliases>

4.3. 内置别名

MyBatis已经给Java很多的内置类设置了别名,你可以直接使用

别名 映射的类型
_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

5. 类型处理器(typeHandlers)

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

提示:从 3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API)

类型处理器 Java 类型 JDBC 类型
BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 数据库兼容的 NUMERICBYTE
ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERICSMALLINT
IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERICINTEGER
LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERICBIGINT
FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERICFLOAT
DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERICDOUBLE
BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERICDECIMAL
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 任何兼容的 NUMERICDOUBLE 类型,存储枚举的序数值(而不是名称)。
SqlxmlTypeHandler java.lang.String SQLXML
InstantTypeHandler java.time.Instant TIMESTAMP
LocalDateTimeTypeHandler java.time.LocalDateTime TIMESTAMP
LocalDateTypeHandler java.time.LocalDate DATE
LocalTimeTypeHandler java.time.LocalTime TIME
OffsetDateTimeTypeHandler java.time.OffsetDateTime TIMESTAMP
OffsetTimeTypeHandler java.time.OffsetTime TIME
ZonedDateTimeTypeHandler java.time.ZonedDateTime TIMESTAMP
YearTypeHandler java.time.Year INTEGER
MonthTypeHandler java.time.Month INTEGER
YearMonthTypeHandler java.time.YearMonth VARCHARLONGVARCHAR
JapaneseDateTypeHandler java.time.chrono.JapaneseDate DATE

6. 对象工厂(objectFactory)

MyBatis查询得到一条记录,将数据封装到对象中,这个对象就是通过objectFactory来创建的。

MyBatis底层有一个默认的对象工厂,来实例化对象。如果你有额外的需求,可以自己写一个对象工厂。但是实际开发中没有重写的必要

7. 插件(plugins)

插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

8. 环境配置(environments)

环境配置就是指配置事务管理器数据源,每一个环境environment就对应一个transactionManagerdataSource

你可以配置多个环境,如开发是连接数据库A,测试时连接数据库。通过<environments>default属性,来决定当前SqlSessionFactory实例选择哪个环境

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- default指定当前使用哪个环境配置 -->
<environments default="development">
<!-- 开发环境设置 -->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- 测试环境设置,连向另一个数据库 -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${test.jdbc.driver}"/>
<property name="url" value="${test.jdbc.url}"/>
<property name="username" value="${test.jdbc.username}"/>
<property name="password" value="${test.jdbc.password}"/>
</dataSource>
</environment>
</environments>

transactionManager是配置事务管理器的,不需要深研。因为Spring的事务管理机制更加强大,实际开发时是使用Spring来管理事务,MyBatis只要知道就这么个东西就可以了

dataSource配置数据源,就是配置连接数据库的一些参数。实际开发时,数据源也是交给Spring管理的,MyBatis只负责CRUD

9. 数据库厂商标识(databaseIdProvider)

Hibernate的数据库移植性非常强,因为所有的SQL都是框架自动生成的。例如项目的数据库从MySQL移植到Oracle,Hibernate会自动检测,在执行时会转为生成Oracle的SQL语句。

但是MyBatis的移植性就没有那么好,因为SQL都是你亲自去写的。如果项目的数据库从MySQL移植到Oracle,你原来的SQL都是针对MySQL的,就会导致项目无法运行。MyBatis考虑到这一情况,就有了databaseIdProvider这一机制。

你可以在全局配置中添加databaseIdProvider

1
2
3
4
5
6
7
8
9
10
11
12
<!-- type="DB_VENDOR"是固定的写法 -->
<databaseIdProvider type="DB_VENDOR">
<!--
name: 数据库厂商的标识,这些标识的值都是固定的,
你可以通过JDBC的Connection的getDatabaseProductName()来获取
value: 给这个标识起一个好用的名字 -->
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql" />
<property name="SQL Server" value="sqlserver" />
</databaseIdProvider>

在写SQL映射文件时,可以根据数据库环境来执行对应的SQL语句。如果匹配到databaseId,则执行对应的SQL,如果匹配不到,则执行没有databaseId的那个SQL

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 如果连接的是Oracle,则执行该语句 -->
<select id="findById" resultType="demo.mybatis.entity.Person" databaseId="oracle">
SELECT * FROM person WHERE person_id = #{personId}
</select>
<!-- 如果连接的是MySQL,则执行该语句 -->
<select id="findById" resultType="demo.mybatis.entity.Person" databaseId="mysql">
SELECT * FROM person WHERE person_id = #{personId}
</select>
<!-- 如果连接的是其它数据库,则执行该语句 -->
<select id="findById" resultType="demo.mybatis.entity.Person">
SELECT * FROM person WHERE person_id = #{personId}
</select>

10. 映射器(mappers)

你写了一些SQL映射文件,MyBatis默认是不知道这些配置文件在哪里的。<mappers>的作用就是告诉MyBatis到哪里去找这些SQL映射文件

10.1. resource使用类路径注册

resources是在类路径下找对应的SQL映射文件

1
2
3
4
5
6
<mappers>
<!-- 给定相对于classpath的路径 -->
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

10.2. url指定网络地址注册

url给出SQL映射文件的网络地址,包括本地路径。在实际开发时,该方式不可取

1
2
3
4
5
6
7
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<!-- Linux路径 -->
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<!-- Windows路径 -->
<mapper url="file:///c:/User.xml" />
</mappers>

10.3. class指定Mapper接口实现注册

class给出指定Mapper接口的全类名。但是光指定Mapper接口,MyBatis怎么知道SQL映射文件在哪里呢?

原因是,在使用class属性时,MyBatis默认认为SQL映射文件被要求放在与对应Mapper接口同一路径下,且名称必须要求。例如UserMapper接口,对应的SQL映射文件名就是UserMapper.xml,也两个文件必须放在同一路径下

1
2
3
4
5
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

10.4. package包扫描注册

package是class方式的扩展。<package>会扫描指定包及其子包下所有的Mapper接口,并找到同一路径下的SQL映射文件。且要求SQL映射文件的名称与Mapper接口的名称必须相同

1
2
3
<mappers>
<package name="demo.mybatis.mapper"/>
</mappers>

注意:实际项目就使用package方式引入映射文件,最方便。而且项目中很可能是基于MyBatis的注解驱动和XML混合开发,SQL映射文件可能就直接被省略了,resource/url的方式直接变得不可用了。此时只能选择class/package方式

panchaoxin wechat
关注我的公众号
支持一下