全局配置文件说明
入门案例中的配置文件mybatis-config.xml,是MyBatis的全局配置文件,包含了MyBatis所有的相关配置项,这些配置会深深影响 MyBatis 行为的设置和属性信息。
配置文件的顶层结构如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
1. 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">
1、 version=“1.0”:声明用的xml版本是1.0;
2、 encoding=“UTF-8”:声明用xml传输数据的时候的字符编码,假如文档里面有中文,编码方式不是UTF-8,传输过去再解码的话中文就会是乱码;
3、 !DOCTYPEconfiguration:DOCTYPE用于声明文档类型,引入DTD文档类型定义(DocumentTypeDefinition)约束,此处表示对于configuration标签下的标签引入了外部mybatis配置文件编写规范,会自动提示及校验配置书写;
2. configuration(配置)
配置文件的根标签,所有的配置都在此标签内。
<configuration>
<!--mybatis配置...-->
</configuration>
3. properties(属性)
properties标签的主要作用是引入外部属性及自定义属性,然后其他配置引入属性使用。
比如在外部文件配置数据库连接属性,然后在数据源配置中引入属性使用,这样就可以实现配置分离,需要改的时候,直接改外部配置文件即可。
<properties resource="mysql.properties" url=""></properties>
resource属性表示引入本地配置文件,url属性表示引入网络资源配置。
使用案例
(1) 引入外部文件配置属性案例
1、 resources目录下添加文件mysql.properties;
db.url=jdbc:mysql://127.0.0.1:3306/angel_admin?serverTimezone=Asia/Shanghai
db.driver=com.mysql.cj.jdbc.Driver
db.username=root
db.password=123456
1、 dataSource数据源配置用使用${}引入外部属性配置;
<?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 resource="mysql.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--驱动名-->
<property name="driver" value="${db.driver}"/>
<!--数据库地址-->
<property name="url"
value="${db.url}"/>
<!--用户名-->
<property name="username" value="${db.username}"/>
<!--密码-->
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!-- 添加mapper XML所在文件夹-->
<mappers>
<package name="org.pearl.mybatis.demo.dao"/>
</mappers>
</configuration>
(2)配置自定义属性案例
1、 添加多个property标签,配置数据库连接信息;
<properties >
<property name="db.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="db.url" value="jdbc:mysql://127.0.0.1:3306/angel_admin?serverTimezone=Asia/Shanghai"/>
<property name="db.username" value="root"/>
<property name="db.password" value="123456"/>
</properties>
1、 dataSource数据源配置用使用${}引入自定义属性;
(3)多个同名属性加载顺序
如果一个属性在不只一个地方进行了配置,比如在resource 及property标签中都配置了db.driver,那么,MyBatis 将按照下面的顺序来加载:
1、 首先读取在properties元素体内指定的属性;
2、 然后根据properties元素中的resource属性读取类路径下属性文件,或根据url属性指定的路径读取属性文件,并覆盖之前读取过的同名属性;
3、 最后读取作为代码方法参数传递的属性,并覆盖之前读取过的同名属性;
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。
(4)占位符指定默认值
从MyBatis 3.4.2 开始,可以为占位符指定一个默认值。
案例演示:
1、 这个特性默认是关闭的要启用这个特性,需要添加一个特定的属性来开启这个特性;
<properties >
<!-- 启用默认值特性 -->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
</properties>
1、 使用:
设置属性的默认值;
<dataSource type="POOLED">
<!--驱动名-->
<property name="driver" value="${db.driver:com.mysql.cj.jdbc.Driver}"/>
<!--数据库地址-->
<property name="url"
value="${db.url:jdbc:mysql://127.0.0.1:3306/angel_admin?serverTimezone=Asia/Shanghai}"/>
<!--用户名-->
<property name="username" value="${db.username:root}"/>
<!--密码-->
<property name="password" value="${db.password:123456}"/>
</dataSource>
1、 当配置的属性名也存在:
时(如:db:username
),此时会有冲突,需要设置自定义的分隔符;
<properties >
<!--添加自定义默认分隔符-->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="?:"/>
</properties>
4. 设置(settings)
这是MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
一个配置完整的 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>
演示案例:
在数据库字段命名规范中,通常使用下划线“_”来连接两个单词,比如:user_type。但是在Java开发中,实体字段通常采用驼峰命名法,因此会在mapper文件的SQL语句中使用 “AS”设置别名来匹配实体。
Mybatis 在 settings 配置项中有一个 mapUnderscoreToCamelCase 参数,设置为True即可开启自动驼峰命名规则映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射,默认为False。
1、 settings标签下添加配置;
<!--驼峰命名 自动将数据库字段下划线转为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
1、 入门案例SQL去掉as;
<select id="selectOneById" resultType="user">
select * from base_user where user_id ={id}
</select>
1、 执行SQL,发现自动完成了下划线字段到实体类驼峰的转换;
5. 类型别名(typeAliases)
在之前mapper XML中设置SQL语句的返回类型resultType时,写的是全限定类名,比较长,所以Mybatis提供了类型别名设置,为Java 类型设置一个短的名字,可以方便我们引用某个类。类很多的情况下,也可以批量设置别名这个包下的每一个类。
<mapper namespace="org.pearl.mybatis.demo.dao.UserMapper">
<select id="selectOneById" resultType="org.pearl.mybatis.demo.pojo.entity.User">
select * from base_user where user_id ={id}
</select>
</mapper>
设置了别名后,resultType就可以直接写别名了,简洁性提升了不少。
<select id="selectOneById" resultType="user">
select * from base_user where user_id ={id}
</select>
(1)使用typeAliases标签
typeAlias可以为某个类设置一个别名。
package可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean并全部设置别名。
<typeAliases>
<!--单个类起别名-->
<typeAlias type="org.pearl.mybatis.demo.pojo.entity.User" alias="user"/>
<!--为某个包起别名 默认别名为类名小写-->
<package name="org.pearl.mybatis.demo.pojo.entity"/>
</typeAliases>
(2)使用@Alias注解
使用@Alias
注解标注在类上,为这个类起别名。
@Data
@Alias("user")
public class User implements Serializable {
值得注意的是,MyBatis已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大小写不敏感的,我们在起别名的时候千万不要占用已有的别名。
6. 类型处理器(typeHandlers)
MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。比如实体类的某个字段是String,在数据库中则会是VARCHAR,他们之间进行交会映射时,都需要转换为自己的类型进行处理。
从3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API) 。MyBatis3.4以前的版本需要我们手动注册这些处理器,以后的版本都是自动注册。
下表描述了一些默认的类型处理器:
可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型,用的最多的应该是枚举类型。
案例演示:
1、 编写类型处理器(会覆盖已有的处理JavaString类型的属性以及VARCHAR类型的参数和结果的类型处理器);
/**
* Created by TD on 2021/6/9
* 类型处理器: String《=》VARCHAR
* 实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler
* MappedJdbcTypes: 指定数据库的数据类型
* BaseTypeHandler泛型: 指定JAVA数据类型
*/
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
/**
* javaType转换成jdbcTpe
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
}
/**
* 将从结果集根据列名称获取到的数据的jdbcType转换成javaType
*/
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
/**
* 将从结果集根据列索引获取到的数据的jdbcType转换成javaType
*/
@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);
}
}
1、 在mybatis全局配置文件中注册处理器,也可通过扫描包下的处理器;
<!--类型处理器-->
<typeHandlers>
<typeHandler handler="org.pearl.mybatis.demo.handler.ExampleTypeHandler"/>
</typeHandlers>
<typeHandlers>
<package name="org.pearl.mybatis.demo.handler"/>
</typeHandlers>
MyBatis 不会通过检测数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指明字段是 VARCHAR 类型, 以使其能够绑定到正确的类型处理器上。这是因为 MyBatis 直到语句被执行时才清楚数据类型。
通过类型处理器的泛型,MyBatis 可以得知该类型处理器处理的 Java 类型,不过这种行为可以通过两种方法改变:
在类型处理器的配置元素(typeHandler 元素)上增加一个 javaType 属性(比如:javaType=“String”);
在类型处理器的类上增加一个 @MappedTypes 注解指定与其关联的 Java 类型列表。 如果在 javaType 属性中也同时指定,则注解上的配置将被忽略。
可以通过两种方式来指定关联的 JDBC 类型:
在类型处理器的配置元素上增加一个 jdbcType 属性(比如:jdbcType=“VARCHAR”);
在类型处理器的类上增加一个 @MappedJdbcTypes 注解指定与其关联的 JDBC 类型列表。 如果在 jdbcType 属性中也同时指定,则注解上的配置将被忽略。
处理枚举类型
若想映射枚举类型 Enum,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选择一个来使用。
比如说我们想存储取近似值时用到的舍入模式。默认情况下,MyBatis 会利用 EnumTypeHandler 来把 Enum 值转换成对应的名字。
<!-- mybatis-config.xml -->
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="java.math.RoundingMode"/>
</typeHandlers>