核心配置文件
配置信息都写在<configuration>
标签中,配置项如下:
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
属性(properties)
之前写的配置属性都在数据源中定义,如:
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/student?useSSL=true&useUnicode=true&charsetEncoding=utf8&severTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="root199962"/>
</dataSource>
我们也可以通过properties属性来实现引用配置文件,数据库的这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
例如,将之前写在外部的db.properties配置文件直接引进来:
<properties resource="db.properties"></properties>
子元素传递的方式(非必须):
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</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>
😉: 取值的方式是不是像JSTL。
当在多个地方进行了配置,MyBatis 将按照下面的顺序来加载:
- 首先读取在 properties 元素体内指定的属性。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
像上面,如果子标签中也定义了属性,则 username 和 password 将会由 properties 元素中设置的相应值来替换。 driver 和 url 属性将会由 db.properties 文件中对应的值来替换。这样就为配置提供了诸多灵活选择。
配置的优先级:通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。
注:从 MyBatis 3.4.2 开始,可以使用占位符的方式。
设置(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>
类型别名(typeAliases)
类型别名是为Java类型设置的一个短的名字。它只和XML配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
<!--配置别名,注意顺序-->
<!-- 可以给实体类起别名 -->
<typeAliases>
<typeAlias type="Eneity.Student" alias="student"></typeAlias>
</typeAliases>
当这样配置时,student
可以用在任何使用Eneity.Student
的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 JavaBean,比如:
<typeAliases>
<package name="Eneity"/>
</typeAliases>
每一个在包 Eneity
中的 Jav Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
当实体类比较少的时候,使用类型别名
如果实体类十分多,建议使用包名
类型别名可以DIY自定义别名,包名则不行,如果非要改,需要在实体类上增加注解
若有注解,则别名为其注解值:
@Alias ("studnet")
public class Studnet {...}
MyBatis已经为许多常见的Java类型内建了相应的类型别名(见官网)。
环境配置(environments)
environments 元素定义了如何配置环境。
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。当配置MyBatis的多套运行环境时,会将SQL映射到多个不同的数据库上,但必须指定其中一个为默认运行环境(通过default指定)。
⚠️:尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境,每个数据库只对应一个 SqlSessionFactory 实例。
<!--只能原则子标签的一个,且为默认值-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</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>
<environment id="test">...</environment>
</environments>
注意几点:
- 默认使用的环境 ID(比如:default=“development”)。
- 每个 environment 元素定义的环境 ID(比如:id=“development”)。
- 事务管理器的配置(比如:type=“JDBC”)。
- 数据源的配置(比如:type=“POOLED”)。
事务管理器(transactionManager)
在 MyBatis 中有两种类型的事务管理器:
- JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
- MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
😉 :如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置。
数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
数据源是必须配置的,有三种内建的数据源类型:UNPOOLED
、POOLED
、JNDI
。
- UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接;
- POOLED: 这种数据源的实现利用“池”(池用完可以回收)的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
- JNDI:这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。
映射器(mappers)
mappers
既然 MyBatis 的行为其他元素已经配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:///
的 URL),或类名和包名等。
映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL语句都必须在xml文件中配置。而从MyBatis 3开始,还支持接口映射器,这种映射器方式允许以Java代码的方式注解定义SQL语句,非常简洁。
引入资源方式
方式一:通过文件类路径引入XML映射器
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>
方式二:通过包名引入映射器接口
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
⚠️:将包内的映射器接口实现全部注册为映射器但是需要配置文件名称和接口名称一致,并且位于同一目录下。
方式三:用类注册引入映射器接口
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
⚠️:使用映射器接口实现类的完全限定类名需要配置文件名称和接口名称一致,并且位于同一目录下。
方式四:用URL注册引入映射器接口
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
Mapper文件
MyBatis 的真正强大在于它的映射语句,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 为聚焦于 SQL 而构建,以尽可能地为你减少麻烦。
文件内容如下:🔻
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Map.StudentMapper">...</mapper>
namespace(命名空间),注意几点:🔻
- namespace命名规则 : 包名+类名
- 作用:绑定接口映射器
mapper标签中放对应于方法的SQL语句,举例如下:🔻
<select id="GetAll" resultType="Student">
select * from student
</select>
⚠️ id:id的内容需要与方法名一致
示意图如下:🔻
其他
类型处理器(typeHandlers)
- 无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。
- 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。
对象工厂(objectFactory)
- MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。
- 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过有参构造方法来实例化。
- 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。
插件(plugins)
MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看 MyBatis 发行包中的源代码。 如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。 因为在试图修改或重写已有方法的行为时,很可能会破坏 MyBatis 的核心模块。 这些都是更底层的类和方法,所以使用插件的时候要特别当心。