properties 属性

这里的 properties 有三种配置方式:

  1. 在 properties 内部标签定义:
1
2
3
4
5
6
<properties>
<property name="jdbc.userName" value="Xorex"/>
<property name="jdbc.password" value="123456"/>
<property name="jdbc.url" value="https://xorex.space/"/>
<property name="jdbc.driver" value="space.xorex.jdbc.Driver"/>
</properties>
  1. 引入外部的配置文件
1
<properties resource="JDBC.properties"/>
  1. 在创建 SqlSessionFactory 的时候,给 Builder 传入一份配置文件。
1
public SqlSessionFactory build(InputStream inputStream, Properties properties);

这三种方式传入的配置信息的优先级是依次递增的,后面的会覆盖前面的配置条目的信息,只需要注意第一种和第二种的优先级关系,有点反常 QAQ。

settings 设置

cacheEnabled

true/false:true

允许缓存:全局性的打开或者关闭缓存设置。

lazyLoadingEnable

true/false:false

允许延迟加载:全局性的打开或者关闭数据库延迟加载,可被 fetchType 覆盖。

aggressiveLazyLoading

true/false:false

侵入式延迟加载:开启时,任一方法的调用都会加载该对象的所有延迟加载属性(被侵入了就不懒加载了)。 否则,每个延迟加载属性会按需加载(所以要懒加载这条必须是 false)

multipleResultSetsEnable

true/false:true

是否允许单语句查询返回多结果集(需要数据库支持),比如一条 <select> 标签里面有两条 select 语句,查询到了两个结果集。

useColumnLabel

true/false:true

使用列标签代替列名,是解决查询结果映射集的一种方法。

1
select userName as user from users;

这样就给 userName 起了一个别名(列标签)user,在进行结果映射的时候,如果开启了 useColumnLabel,那么就用别名 user 去找结果映射填充而不是原名的 userName。建议一直开着

useGeneratedKeys

true/false:false

在调用 insert 和 update 语句更新数据库的时候,允许 JDBC 自动生成主键,并将主键内容返回给传入参数的 keyProperty 一项。

也就是传入一个 User 实例后,利用 userName 和 password 插入数据库,数据库生成的主键回赋值给传入参数 id 属性。

这个在 settings 设置之后,只对接口映射器有效(也就是在 Mapper 接口处使用注解开发),而对 XML 映射器无效。因此如果想要 XML 处实现,则需要到具体的 insert 和 update 语句里面设置:useGeneratedKyes="true" keyProperty="id" 打开开关并指定赋值主键的属性。

autoMappingBehavior

NONE/PARTIAL/FULL:PARTIAL

表示自动结果映射行为的等级,none 表示不自动映射,partial [pɑːrʃl] 局部的,表示只会自动映射没有定义嵌套结果映射的字段,FULL 自动映射任何复杂的结果集,无论是否有嵌套。

不过一般默认的 PARTIAL 级别就够用了,FULL 就有点不太可控了,对于嵌套映射,还是自己写一个 ResultMap 爽。

autoMappingUnknowColumnBehavior

NONE/WARNING/FAILING:NONE

表示开启自动映射的时候,遇到未知列或者未知属性的时候,应该怎么做。

NONE 表示什么都不做,WARNING 表示日志输出 WARN 级别,FAILING 表示抛出 SqlSessionException。

defaultExecutorType

SIMPLE/REUSE/BATCH:SIMPLE

配置默认的执行器,SIMPLE 为简单执行器,没执行一句 SQL 就创建一个新的 Statement 实例。REUSE 为重复使用执行器,将执行过的 Statement 实例放入 Map 中缓存,方便下次相同 SQL 语句使用。BATCH 为批量执行器,会将多个 SQL 一次性执行。

defaultStatementTimeout

正整数:null

设置 Mybatis 等待数据库响应的最长时间,默认没有设置,单位秒。

defaultFetchSize

正整数:null

设置 Mybatis 获取 SQL 结果集的缓冲区大小的建议值,避免因为结果集数据过大,单位为条。

mapUnderScoreToCamelCase

true/false:false

设置将数据库列里面的下划线命名法和 Java 中的驼峰命名法进行映射匹配。

……

其实还有很多很多设置,但是时间和精力关系,就先这样了,等学到后面回把这些补上的。

typeAliases 别名

TypeAliases 主要作用就是为我们自己写的 POJO 起别名,这样只要遇到需要写全类名的地方,都可以用别名来代替。需要注意的是,所有的别名都是不区分大小写的!!!

单独指定

1
2
3
<typeAliases>
<typeAlias type="space.xorex.mybatis.POJO.User" alias="user" />
</typeAliases>

单独给某一个类指定任意一个名字作为他的别名。


或者使用注解 @Alias("name") 标注在需要别名的 POJO 的申明类上面,也可以起别名。

整个包执行

1
2
3
<typeAliases>
<package name="space.xorex.mybatis.POJO"/>
</typeAliases>

会将 space.xorex.mybatis.POJO 下面所有的 POJO 都起一个和类名相同不区分大小写的别名。

MyBatis 内部设置的别名

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

typeHandlers 类型处理器

类型处理器主要的工作内容就是将 SQL 数据库中的数据类型和 Java 的数据类型做一个转化,MyBatis 本身已经内置了很多类型处理器了,基本足够我们使用,但是如果想要实现自己的 typeHandler 的话,也不是不可以,只需要实现 TypeHandler 接口或者继承 BaseTypeHandler 即可。

实现完自己 typeHandler 后,需要将其加入 MyBatis 全局配置文件的 <typeHandlers> 里面:

1
2
3
<typeHandlers>
<typeHandler handler="space.xorex.handlers.MyHandler" />
</typeHandlers>

objectFactory 对象工厂

这个没啥可说的,就是单纯的用来创造一个填充数据库查询来的数据的对象实例。这个选项的意义就是当自己实现了 objectFactory 之后,将自己的实现的工厂替换 MyBatis 自带的工厂。

1
<objectFactory type="space.xorex.mybatis.objectFactorys.MyObjectFactory" />

plugins 插件

插件的作用其实就是一个拦截器,它可以拦截 MyBatis 里面的四大组件:

1
2
3
4
Executor(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) //负责 SQL 语句的执行
ParameterHandler(getParameterObject, setParameters) //负责参数的填充
ResultSetHandler(handleResultSets, handleOutputParameters) //负责查询结果集的映射
StatementHandler(prepare, parameterize, batch, update, query) //负责 SQL 语句的构造

我们只要实现了 Interceptor 接口,就可以在这个拦截器里面对上面类里面的任意执行方法进行拦截,比如执行器 Executor 的更新方法 update(),然后加入一些自定义的东西。最后加入到配置中就生效了。

1
2
3
<plugins>
<plugin interceptor="space.xorex.mybatis.interceptors.MyInterceptors" />
</plugins>

environment 环境

MyBatis 里面的环境就是数据库相关的配置,在 <environments> 标签里面可以添加多个数据库环境配置,然后在 default 选项里面指明要使用的环境 id 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
<environments default="Dep-Env">
<environment id="Test-Env">
<transactionManager/>
<dataSource>
</dataSource>
</environment>

<environment id="Dep-Env">
<transactionManager/>
<dataSource>
</dataSource>
</environment>
</environments>

其中 transactionManager 标签主要是设置事务管理的级别,其属性 type 有两个选项 JDBC/MANAGED ,JDBC 指的是使用 JDBC 自带的 commit rollback 进心事务管理,而 MANAGED 表示啥都不做。

当我们单独使用 MyBatis 的时候,可以用 JDBC 来控制事务。而和 Spring 整合之后,所以这条可以不配置(Spring 的事务控制的配置会直接覆盖 MyBatis 的!)

其次的 dataSource 用来配置数据源,其属性 type 有 UNPOOLED/POOLED/JNDI,UNPOOLED 表示一次访问新建一个连接,POOLED 表示使用连接池来优化连接,JNDI 是在 EJB 服务器上使用的,这个可以先不管。

然后 dataSource 里面就是设置各种数据源的信息了。


当我们使用 Spring 进行整合的时候,上面的配置其实都没啥用(也不需要配置),我们将数据源和事务管理都交给 Spring 来完成,MyBatis 做好自己的 CRUD 即可。

databaseIdProvider 数据库厂商标识

这个主要是用来设置多数据库连接的时候,一个数据库厂商标识别名的问题,其中属性 type 的值 DB_VENDOR 是固定的,表示通过方法 DatabaseMetaData#getDatabaseProductName() 自动获取当前数据库连接的数据库厂商标识。

获取标识之后,会在下面 property 标签里面的 name 属性匹配相同的数据库厂商标识,然后给它设置一个别名,为 value 里面的值。

1
2
3
4
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>

设置别名是为了方便,但是要在那里需要这个数据库厂商标识别名呢,答案就是在 Mapper.xml 的 SQL 语句映射文件里面,每一句 SQL 标签都有一个属性 databaseId 里面可以填写数据库厂商标识别名,标识这句 SQL 是在对应数据库上执行的。这样面对不停切换的数据库源,可以轻松的用不同 SQL 语句来应对。

1
2
3
4
5
6
<select id="getAllUsers" resultType="user" databaseId="mysql">
select * from users;
</select>
<select id="getAllUsers" resultType="user" databaseId="sqlserver">
select * from users;
</select>

mappers 映射器

用来找 SQL 的 mapper.xml 映射文件的,分为单个配置和批量配置:

单个配置

使用 mapper 标签,resource 是从类路径下面开始找的指定配置文件,class 根据接口全类名在同级目录下找同名配置文件的,url 是从磁盘(格式为本地文件传输协议 file:/// )或者网络上根据路径找的映射文件。

1
2
3
4
5
<mappers>
<mapper resource="space/xorex/mybatis/Mapper/UserMapper.xml"/>
<mapper class="space.xorex.mybatis.Mapper.UserMapper" />
<mapper url="file:///D:/MyBatis/src/main/java/space/xorex/mybatis/Mapper/UserMapper.xml" />
</mappers>

批量配置

1
2
3
<mappers>
<package name="space.xorex.mybatis.Mapper" />
</mappers>

使用 package 标签,设置一个包名,然后会自动在包的同级目录下面找到所有的 xml 映射文件,根据类和 xml 文件名称相同进行匹配。

优先级问题

需要注意的是,四者完全冲突,建议一个 mapper 只使用一种方法进行映射。