这段内容是关于 MyBatis 框架的配置(Configuration) 的详细说明,出自 MyBatis 官方文档。它解释了 mybatis-config.xml
文件中各个配置项的作用、用法和优先级。
我们可以从整体结构出发,逐部分来理解这个配置文件的核心组成部分。
🌐 一、MyBatis 配置文件的整体结构
xml
<configuration>
<properties />
<settings />
<typeAliases />
<typeHandlers />
<objectFactory />
<plugins />
<environments />
<databaseIdProvider />
<mappers />
</configuration>
这是 MyBatis 主配置文件的标准结构。每一部分都有特定的功能,下面我们逐一解读。
🔧 1. <properties>
------ 外部属性配置(类似 application.properties)
作用:用于定义可替换的变量,实现配置外部化(比如数据库连接信息),便于不同环境切换。
✅ 使用方式:
xml
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
resource
:引用 classpath 下的.properties
文件。- 内部
<property>
可以覆盖 properties 文件中的值。
💡 在其他地方使用 ${}
占位符引用:
xml
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
⚖️ 属性加载顺序(优先级由低到高):
<properties>
标签内的 property 定义;resource
或url
加载的外部 properties 文件;- 通过 Java 代码传入的参数(如
SqlSessionFactoryBuilder.build(reader, props)
)------ 最高优先级!
示例:
props.put("username", "prod_user")
会覆盖前面所有定义。
🎯 默认值支持(MyBatis 3.4.2+)
xml
<property name="username" value="${username:ut_user}"/>
表示如果未设置 username
,则默认为 ut_user
。
⚠️ 但该功能默认关闭!需要开启:
xml
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
还可以自定义分隔符避免冲突(例如 OGNL 表达式中有 :
):
xml
<property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/>
<property name="username" value="${db:username?:guest}"/>
⚙️ 2. <settings>
------ 运行时行为调优
这是 MyBatis 最重要的运行时配置,直接影响其性能和行为。
设置项 | 说明 | 推荐值 |
---|---|---|
cacheEnabled |
是否启用二级缓存 | true |
lazyLoadingEnabled |
是否开启懒加载 | true |
aggressiveLazyLoading |
调用任意方法是否触发懒加载 | false (推荐) |
autoMappingBehavior |
自动映射级别: NONE/PARTIAL/FULL | PARTIAL |
mapUnderscoreToCamelCase |
下划线转驼峰命名 | true (常用) |
useGeneratedKeys |
是否使用 JDBC 自动生成主键 | true (插入后获取 ID) |
defaultExecutorType |
执行器类型:SIMPLE / REUSE / BATCH | SIMPLE (BATCH 用于批量) |
logImpl |
日志实现(SLF4J、LOG4J2 等) | 建议设为 SLF4J |
📌 示例:
xml
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<setting name="logImpl" value="SLF4J"/>
</settings>
👉 这些设置非常关键,建议根据项目需求合理调整。
📦 3. <typeAliases>
------ 类型别名
作用:给全类名起一个短名字,减少 XML 中重复书写。
✅ 方式一:单个别名定义
xml
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
</typeAliases>
之后可以用 Author
代替 domain.blog.Author
。
✅ 方式二:包扫描自动注册
xml
<typeAliases>
<package name="domain.blog"/>
</package>
</typeAliases>
- 默认规则:类名小写作为别名 →
Author
→author
- 若想自定义别名,可在类上加注解:
java
@Alias("myAuthor")
public class Author { ... }
✅ 内建别名(无需配置)
MyBatis 提供了很多常见类型的别名,如:
别名 | 对应类型 |
---|---|
int / integer |
Integer |
string |
String |
list |
List |
date |
Date |
map |
Map |
注意:这些别名不区分大小写。
🔄 4. <typeHandlers>
------ 类型处理器
作用:负责 Java 类型与 JDBC 类型之间的转换。
例如:Java 的 String
↔ SQL 的 VARCHAR
,或枚举 ↔ 数据库存储值。
✅ 内置 TypeHandler 示例:
Java 类型 | JDBC 类型 | Handler |
---|---|---|
String | VARCHAR/CLOB | StringTypeHandler |
Integer | INTEGER | IntegerTypeHandler |
Date | TIMESTAMP | DateTypeHandler |
Enum | VARCHAR/INTEGER | EnumTypeHandler / EnumOrdinalTypeHandler |
✅ 自定义 TypeHandler(如处理 JSON 字段)
java
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, new Gson().toJson(parameter));
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return new Gson().fromJson(rs.getString(columnName), String.class);
}
// ...
}
注册:
xml
<typeHandlers>
<typeHandler handler="com.example.JsonTypeHandler"/>
</typeHandlers>
🎯 枚举处理技巧
EnumTypeHandler
: 存储枚举名称(字符串)EnumOrdinalTypeHandler
: 存储序号(数字)
xml
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="java.math.RoundingMode"/>
你也可以在 Mapper 映射中显式指定某个字段使用哪种处理器。
🏗️ 5. <objectFactory>
------ 对象工厂
MyBatis 创建结果对象时使用的工厂,默认使用无参构造函数创建实例。
可以自定义,比如结合依赖注入框架(Spring)。
xml
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
一般情况下不需要修改。
🔌 6. <plugins>
------ 插件(拦截器)
MyBatis 允许你在执行过程中"拦截"某些核心方法,实现扩展功能,如:
- 分页插件(PageHelper)
- SQL 打印日志
- 性能监控
- 数据权限控制
✅ 实现 Interceptor 接口:
java
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class ExamplePlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("Before query...");
Object result = invocation.proceed(); // 继续执行
System.out.println("After query.");
return result;
}
@Override
public void setProperties(Properties properties) {
// 接收配置参数
}
}
注册:
xml
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="debug" value="true"/>
</plugin>
</plugins>
⚠️ 插件强大但危险,不要随意修改核心逻辑。
🌍 7. <environments>
------ 环境配置(数据源 + 事务管理)
允许配置多个环境(开发、测试、生产),但每次只能使用一个。
xml
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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="production">
<!-- 生产环境配置 -->
</environment>
</environments>
✅ transactionManager 类型:
JDBC
: 使用 JDBC 原生事务(commit/rollback),适合独立应用。MANAGED
: 让容器(如 Spring、JEE)管理事务,MyBatis 不主动提交或关闭连接。
⚠️ 使用 Spring 时,MyBatis 的事务会被 Spring 覆盖,所以不用特别配置。
✅ dataSource 类型:
UNPOOLED
: 每次新建连接,简单但慢。POOLED
: 使用连接池(推荐),提高性能。JNDI
: 从 JNDI 获取数据源(企业级应用服务器中使用)。
POOLED 参数举例:
xml
<dataSource type="POOLED">
<property name="poolMaximumActiveConnections" value="20"/>
<property name="poolMaximumIdleConnections" value="10"/>
<property name="poolTimeToWait" value="20000"/>
</dataSource>
🧩 8. <databaseIdProvider>
------ 多数据库支持
作用:根据不同数据库厂商执行不同的 SQL 语句。
xml
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="Oracle" value="oracle"/>
<property "MySQL" value="mysql"/>
</databaseIdProvider>
然后在 Mapper XML 中:
xml
<select id="getUsers" resultType="User" databaseId="mysql">
SELECT * FROM users LIMIT 10
</select>
<select id="getUsers" resultType="User" databaseId="oracle">
SELECT * FROM (SELECT * FROM users) WHERE ROWNUM <= 10
</select>
这样就可以根据不同数据库写出适配的 SQL。
🗺️ 9. <mappers>
------ 注册 SQL 映射文件或接口
告诉 MyBatis 到哪里去找 SQL 映射。
四种方式:
xml
<!-- 1. 引用 XML 文件 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
<!-- 2. 使用 URL(少见) -->
<mapper url="file:///D:/mappers/UserMapper.xml"/>
<!-- 3. 注册 Mapper 接口 -->
<mapper class="com.example.UserMapper"/>
<!-- 4. 扫描整个包(推荐) -->
<package name="com.example.mapper"/>
⚠️ 如果使用接口绑定模式(推荐做法),必须保证:
- XML 文件与接口同名且在同一目录;
- namespace 等于接口全路径名;
- 方法名与 SQL id 一致。
✅ 总结:如何理解 MyBatis 配置?
配置项 | 功能简述 | 是否常用 |
---|---|---|
<properties> |
外部化配置,支持占位符 | ✅ 必用 |
<settings> |
控制 MyBatis 行为(懒加载、驼峰等) | ✅ 必调 |
<typeAliases> |
简化类名书写 | ✅ 推荐 |
<typeHandlers> |
自定义类型转换逻辑 | ❓ 按需 |
<objectFactory> |
自定义对象创建方式 | ❌ 少用 |
<plugins> |
拦截执行过程,增强功能 | ✅ 常见(分页) |
<environments> |
数据源和事务管理 | ✅ 必配 |
<databaseIdProvider> |
多数据库兼容 | ✅ 多库项目必用 |
<mappers> |
注册 SQL 映射位置 | ✅ 必配 |
📝 实际开发建议
- 使用
properties
文件管理数据库配置 - 开启
mapUnderscoreToCamelCase
支持下划线转驼峰 - 合理配置
lazyLoadingEnabled
和aggressiveLazyLoading
- 使用连接池(POOLED)提升性能
- 通过
plugins
引入分页插件(如 PageHelper) - 使用 package 扫描自动注册 mappers
- 多数据库场景下使用
databaseIdProvider
如果你正在学习 MyBatis,建议先掌握:
properties
+environments
+mappers
→ 基础运行settings
中的mapUnderscoreToCamelCase
和useGeneratedKeys
typeAliases
简化类名- 后续再深入
typeHandlers
和plugins
如有具体问题(比如"怎么配置 MySQL 分页?"、"枚举怎么存数据库?"),欢迎继续提问!