七年老码农揭秘 MyBatis 核心配置文件:从踩坑到丝滑配置的通关秘籍
各位 CRUD 江湖的道友们好,我是那个在 MyBatis 配置文件里栽过 7 次跟头的老码农。还记得五年前第一次配置 MyBatis,把数据源密码写错导致项目启动报错,被运维小哥指着日志问 "你是不是把测试库密码写成生日了"—— 从此养成了对着配置文件逐行核对的习惯。今天就把核心配置文件的 "十八般武艺" 拆解开来,用接地气的人话带你吃透每个配置项,顺便聊聊那些年因为配置错误踩过的坑。
一、先搞懂核心配置文件:MyBatis 的 "全局设置面板"
MyBatis 的核心配置文件(通常是mybatis-config.xml)就像游戏里的设置界面,决定了整个 ORM 框架的运行规则。它主要管三件大事:
- 环境配置:数据库连接怎么配?事务怎么管?
- 映射器注册:去哪里找写好的 SQL 语句?
- 全局参数:日志要不要开?驼峰命名转不转?
当年我误以为这个文件只是 "走流程",随便复制一份模板就用,结果因为没配置分页插件导致大数据量查询超时,被产品经理骂到怀疑人生 —— 记住:核心配置文件是 MyBatis 的地基,地基不稳,后面写 SQL 再漂亮也白搭。
二、核心配置文件的 "灵魂七要素",逐个拆解给你看
1. :整个配置文件的 "总指挥官"
这是根标签,所有配置项都要放在里面,就像给配置文件套了个 "保护壳"。没啥特殊配置,但少了它整个文件就失效,当年我手滑删掉这个标签,启动直接报XML解析错误,Debug 半小时才发现问题 ——千万别手抖删根标签。
2. :数据库配置的 "快捷方式"
作用:引入外部属性文件(如db.properties),避免硬编码。
<properties resource="db.properties" />
db.properties内容:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test_db
jdbc.username=root
jdbc.password=123456
最佳实践:
- 开发 / 测试 / 生产环境用不同属性文件,通过spring.profiles.active切换
- 敏感信息(密码)建议用配置中心(如 Apollo),别直接写在文件里我曾在测试环境用了生产库密码,幸亏被同事及时发现,不然就要写 "事故报告" 了。
3. :MyBatis 的 "高级设置",细节控必看
这是最容易提升开发体验的配置项,相当于给 MyBatis 开 "作弊码"。常用配置:
| 配置项 | 说明 | 我的血泪教训 |
|---|---|---|
| logImpl | 日志实现(如LOG4J、STDOUT_LOGGING),调试 SQL 必开! | 刚学的时候没开日志,写了三天错误 SQL,最后发现是#{}写成了${},开日志后 10 分钟定位问题 |
| mapUnderscoreToCamelCase | 自动将数据库下划线字段映射到驼峰属性(如user_name→userName) | 项目里实体类用驼峰,数据库用下划线,没配这个导致查询结果全是空值,debug 到凌晨两点 |
| defaultExecutorType | 执行器类型(SIMPLE/REUSE/BATCH),批量操作选BATCH提升性能 | 批量插入 10 万条数据时没配BATCH,耗时 30 分钟,配完后直接缩到 2 分钟,香到流泪 |
配置示例:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
4. :给 Java 类型起 "外号",代码更简洁
作用:给长类名起别名,比如com.example.User→User。
<!-- 单个类型别名 -->
<typeAlias type="com.example.User" alias="User" />
<!-- 批量扫描包,自动生成别名(默认别名是类名小写) -->
<package name="com.example.entity" />
注意:
- 别和 MyBatis 内置别名冲突(如int→_int,string→string)
- 自定义别名建议用首字母小写,和 MyBatis 默认规则一致我曾给OrderDetail起别名OD,结果同事看代码时问 "这 OD 是啥?奥特曼吗?",后来统一用类名小写,世界清净了。
5. :数据库环境配置,多套环境随便切
这是核心配置中的核心,相当于给 MyBatis 指定 "连接哪个数据库"。支持配置多个环境(开发 / 测试 / 生产),通过default指定默认环境。
▶ :事务管理器,数据库的 "事务管家"
- JDBC:直接使用 JDBC 的事务(connection.commit()),简单粗暴
- MANAGED:由容器管理事务(如 Spring),微服务项目必选
<transactionManager type="JDBC" />
<!-- 或 -->
<transactionManager type="MANAGED" />
当年在 Spring Boot 项目里用了JDBC事务,结果发现事务不回滚,才想起应该用MANAGED让 Spring 管理,踩坑 + 1。
▶ :数据源,数据库的 "连接工厂"
常用POOLED(带连接池)或UNPOOLED(不带连接池),生产环境必选POOLED:
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
调优参数:
- poolMaximumActiveConnections:最大活跃连接数(默认 10,高并发调大到 50)
- poolMaximumIdleConnections:最大空闲连接数(默认 5,低负载调低省资源)我曾在秒杀项目里没调连接数,导致数据库连接池爆满,最后加poolMaximumActiveConnections="100"才扛住流量。
6. :注册 SQL 映射文件,MyBatis 的 "弹药库"
告诉 MyBatis 去哪里找写好的 SQL,有三种方式,推荐第三种:
▶ 方式一:单个映射器注册(适合少量映射文件)
<mapper resource="mapper/UserMapper.xml" />
▶ 方式二:通过接口类注册(接口和映射文件同名同路径)
<mapper class="com.example.mapper.UserMapper" />
▶ 方式三:批量扫描包(推荐,懒人福音)
<package name="com.example.mapper" />
必坑点:
- 映射文件必须和接口在同一包下,且文件名相同(比如UserMapper.java对应UserMapper.xml)
- 别漏了resource或classpath路径,我曾把映射文件放在src/main/java下没编译,导致启动报找不到映射器,排查三小时才发现是路径错误
7. :插件扩展,MyBatis 的 "外挂市场"
常用插件:
- PageHelper:分页神器,一行代码实现分页查询
- MyBatis-Plus:增强工具,自带 CRUD 接口,减少 90% 重复代码
- Interceptor:自定义拦截器,比如添加公共查询条件(租户 ID、数据权限)
配置示例(PageHelper):
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 分页参数合理化,防止页码为负数 -->
<property name="reasonable" value="true" />
</plugin>
</plugins>
当年用 MyBatis 写分页,手动计算limit offset,写错一次后怒装 PageHelper,从此告别 "分页计算恐惧症"。
三、实战案例:开发 / 生产环境不同配置怎么搞?
假设我们有两套环境,配置文件这样写:
<environments default="development">
<!-- 开发环境 -->
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${dev.jdbc.driver}" />
<property name="url" value="${dev.jdbc.url}" />
<property name="username" value="${dev.jdbc.username}" />
<property name="password" value="${dev.jdbc.password}" />
</dataSource>
</environment>
<!-- 生产环境 -->
<environment id="production">
<transactionManager type="MANAGED" />
<dataSource type="POOLED">
<property name="driver" value="${prod.jdbc.driver}" />
<property name="url" value="${prod.jdbc.url}" />
<property name="username" value="${prod.jdbc.username}" />
<property name="password" value="${prod.jdbc.password}" />
<!-- 生产环境调优参数 -->
<property name="poolMaximumActiveConnections" value="200" />
</dataSource>
</environment>
</environments>
通过default切换环境,配合properties引入不同环境的配置文件,再也不用手动改数据库地址了。
四、避坑指南:这 5 个配置错误,我替你们踩过了
1. 数据源密码写错:启动报 "Authentication failed"
当年把password写成passw0rd(数字 0 当字母),启动一直连不上数据库,最后对着键盘检查五分钟才发现问题 ——建议复制粘贴密码,别手动输入。
2. 没配置mapUnderscoreToCamelCase:查询结果为空
实体类属性是userName,数据库字段是user_name,没开驼峰映射,导致查询结果所有属性都是null,debug 时还以为是 SQL 写错,结果是配置没开,血的教训。
3. 映射器路径错误:启动报Invalid bound statement
把映射文件放在src/main/resources/mapper下,但配置里写的是com/example/mapper/UserMapper.xml,路径不对,导致 MyBatis 找不到 SQL 语句 ——记住:resource 路径是从 classpath 根开始,别加多余包名。
4. 事务管理器类型选错:事务不回滚
在 Spring Boot 项目里用了JDBC事务管理器,结果抛异常后数据没回滚,因为 Spring 的声明式事务需要MANAGED类型,让 Spring 来管理事务,而不是 MyBatis 自己管。
5. 插件顺序搞错:分页结果异常
先注册了自定义拦截器,再注册 PageHelper,导致分页参数被拦截器修改,结果页码错乱。MyBatis 插件是按注册顺序执行的,记得把 PageHelper 放在最前面。
五、总结:核心配置文件是 MyBatis 的 "隐形翅膀"
折腾了五年 MyBatis,现在看到核心配置文件就像看到老朋友:
- 环境配置是地基,决定了数据库连接的稳定性
- settings 配置是润滑剂,提升开发和运行效率
- mappers 配置是弹药库,没它 SQL 再牛也打不出伤害
最后送大家一句口诀:核心配置别嫌烦,逐项检查保平安,环境配置看清楚,映射路径别搞混,插件顺序要记牢,驼峰映射不能少,细节做好无 Bug,代码写得呱呱叫!
如果你在配置 MyBatis 时遇到诡异问题,不妨对照这篇文章检查一遍,大概率能找到答案。