MyBatis的核心 XML 配置文件的配置有严格的顺序限制,不能颠倒
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource=""/>
<properties>
<property name="" value=""/>
properties>
<settings>
<setting name="" value=""/>
settings>
<typeAliases >
<package name="net.biancheng.po"/>
<typeAlias type="类的路径" alias="别名"/>
<typeAlias type="类路径"/>
typeAliases>
<typeHandlers>
<typeHandler handler="处理器路径" jdbcType="定义数据库类型" javaType="定义 Java 类型"/>
typeHandlers>
<objectFactory type="">
<property name="" value=""/>
objectFactory>
<plugins>
<plugin interceptor="">plugin>
plugins>
<environments default="">
<environment id="">
<transactionManager type="">transactionManager>
<dataSource type="">
<property name="" value=""/>
dataSource>
environment>
environments>
<databaseIdProvider type="">databaseIdProvider>
<mappers>
<mapper resource=""/>
mappers>
configuration>
properties主要是配置运行参数,它提供了三种使用方式:
property子元素
<properties>
<property name="database.driver" value="com.mysql.cj.jdbc.Driver"/>
properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
dataSource>
environment>
environments>
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/库名?useUnicode=true&&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=密码
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
dataSource>
environment>
environments>
程序代码传递(可能有些数据是加密的所以必须要先破解后才能使用,所以可以使用这种方式破解后进行替换)
private static SqlSessionFactory factory;
static {
try {
//先获取properties配置文件
InputStream in = Resources.getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
//对加密信息进行破解
//获取mybatis的配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//获取工厂,替换成properties里的配置文件
factory = new SqlSessionFactoryBuilder().build(inputStream,properties);
} catch (IOException e) {
e.printStackTrace();
}
}
提供了众多的配置,不需要大规模配置,大部分情况下使用默认的即可。
<settings>
全局性地开启或关闭缓存,默认true
<setting name="cacheEnabled" value="true"/>
延迟加载,当开启时,关联对象都会延迟加载。默认false
<setting name="lazyLoadingEnabled" value="true"/>
日志
<setting name="logImpl" value="LOG4J"/>
是否允许单个语句返回多结果集(需要数据库驱动支持)。默认true
<setting name="multipleResultSetsEnabled" value="true"/>
使用列标签代替列名,需要数据库驱动支持。。默认true
<setting name="useColumnLabel" value="true"/>
允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。
<setting name="useGeneratedKeys" value="false"/>
指定 MyBatis 应如何自动映射列到字段或属性。
NONE 表示关闭自动映射;
PARTIAL (默认)只会自动映射没有定义嵌套结果映射的字段。
FULL 会自动映射任何复杂的结果集(无论是否嵌套)。
<setting name="autoMappingBehavior" value="PARTIAL"/>
指定发现自动映射目标未知列(或未知属性类型)的行为。
NONE(默认): 不做任何反应
WARNING: 输出警告日志
FAILING: 映射失败 (抛出 SqlSessionException)
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
配置默认的执行器。
SIMPLE(默认) 就是普通的执行器;
REUSE 执行器会重用预处理语句(PreparedStatement);
BATCH 执行器不仅重用语句还会执行批量更新。
<setting name="defaultExecutorType" value="SIMPLE"/>
设置超时时间,决定数据库驱动等待数据库响应的秒数。
<setting name="defaultStatementTimeout" value="25"/>
为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。
<setting name="defaultFetchSize" value="100"/>
是否允许在嵌套语句中使用分页(RowBounds)。允许使用则为 false。默认false
<setting name="safeRowBoundsEnabled" value="false"/>
是否允许在嵌套语句中使用结果处理器(ResultHandler)。允许使用则为 false。默认false
<setting name="safeResultHandlerEnabled" value="false"/>
是否开启驼峰命名自动映射, A_COLUMN →aColumn
<setting name="mapUnderscoreToCamelCase" value="false"/>
默认值为 SESSION,会缓存一个会话中执行的所有查询。
<setting name="localCacheScope" value="SESSION"/>
当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。
<setting name="jdbcTypeForNull" value="OTHER"/>
指定对象的哪些方法触发一次延迟加载。
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
settings>
XML文件中的映射关系都是使用的类全限定名,有些全限定名很长,所以可以通过此标签设置别名来代替全限定名。
系统自定义别名:MyBatis初始化时,已经自动初始化的一些别名(我们常用的Sting、基本数据类型、集合等等)
XML自定义单个类的别名
在XML配置文件中配置别名后
<typeAliases>
<typeAlias alias="user" type="com.yu.entity.User"/>
typeAliases>
在映射文件中可以直接使用别名
<select id="findAll" resultType="user"> 如果没有配置typeAlias,则需要写全限定名
select>
直接扫描包,包内的类的别名为首字母变成小写
<typeAliases>
<package name="包名"/>
typeAliases>
注解
@Alias("user")
public class User {
...
}
typeHandlers 主要将获取的值合理地转化为 Java 类型。在 typeHandler 中,分为 jdbcType 和 javaType,其中 jdbcType 用于定义数据库类型,而 javaType 用于定义 Java 类型,typeHandler 的作用就是承担 jdbcType 和 javaType 之间的相互转换。
我们知道数据库的数据类型和Java的数据类型是不一样的,所以需要typeHandlers 来进行转换。MyBatis针对这些数据类型内部已经定义了很多的 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 类型,存储枚举的索引(而不是名称)。 |
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 | VARCHAR or LONGVARCHAR |
JapaneseDateTypeHandler | java.time.chrono.JapaneseDate | DATE |
这些内置的转换器基本能适应大多数适应,但也有需要自己配置的情况(如枚举),自定义TypeHandler需要实现org.apache.ibatis.type.TypeHandler接口,或继承一个很便利的类org.apache.ibatis.type.BaseTypeHandler,然后可以选择性地将它映射到一个JDBC类型。。
public class MyTypeHandler implements TypeHandler<String> {
//将java类型转换为数据库需要的类型
@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
}
//将数据库中的类型转换为java类型
@Override
public String getResult(ResultSet rs, String columnName) throws SQLException {
return null;
}
//将数据库中的类型转换为java类型
@Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
return null;
}
//将数据库中的类型转换为java类型
@Override
public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
return null;
}
}
配置TypeHandler
<typeHandlers>
<typeHandler javaType="string" jdbcType="VARCHAR" handler="com.yu.util.MyTypeHandler"/>
typeHandlers>
在MyBatis返回结果集时,就会使用一个对象工厂来创建这个结果集对应的实例。MyBatis有一个默认的对象工厂 org.apache.ibatis.reflection.factory.DefaultObjectFactory完成相应的工作,它实现了org.apache.ibatis.reflection.factory.ObjectFactory 接口。
ObjectFactory 就是底层接口,我们可以同时实现它来自定义对象工厂,但一般情况下不会这么做。
public interface ObjectFactory {
/**设置配置属性。*/
default void setProperties(Properties properties) {
// NOP
}
/**使用默认构造函数创建一个新对象*/
<T> T create(Class<T> type);
/**使用指定的构造函数和参数创建一个新对象。 */
<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
/**如果此对象可以具有一组其他对象,则返回 true。 */
<T> boolean isCollection(Class<T> type);
}
environments主要的作用是配置数据库信息,内部可以配置多个数据库信息,然后选择一个。
environment(环境变量)
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
dataSource>
environment>
environments>
映射器是Mybatis的核心组件,而mappers标签就是为了引入映射器。
通过具体的文件引入
<mappers>
<mapper resource="mapping的全限定名"/>
</mappers>
通过包名引入包内所有的映射器
<mappers>
<mapper resource="mapping所在的包名"/>
</mappers>