MyBatis核心配置文件:从踩坑到丝滑配置的通关秘籍

281 阅读4分钟

七年老码农揭秘 MyBatis 核心配置文件:从踩坑到丝滑配置的通关秘籍

各位 CRUD 江湖的道友们好,我是那个在 MyBatis 配置文件里栽过 7 次跟头的老码农。还记得五年前第一次配置 MyBatis,把数据源密码写错导致项目启动报错,被运维小哥指着日志问 "你是不是把测试库密码写成生日了"—— 从此养成了对着配置文件逐行核对的习惯。今天就把核心配置文件的 "十八般武艺" 拆解开来,用接地气的人话带你吃透每个配置项,顺便聊聊那些年因为配置错误踩过的坑。

一、先搞懂核心配置文件:MyBatis 的 "全局设置面板"

MyBatis 的核心配置文件(通常是mybatis-config.xml)就像游戏里的设置界面,决定了整个 ORM 框架的运行规则。它主要管三件大事:

  1. 环境配置:数据库连接怎么配?事务怎么管?
  1. 映射器注册:去哪里找写好的 SQL 语句?
  1. 全局参数:日志要不要开?驼峰命名转不转?

当年我误以为这个文件只是 "走流程",随便复制一份模板就用,结果因为没配置分页插件导致大数据量查询超时,被产品经理骂到怀疑人生 —— 记住:核心配置文件是 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 时遇到诡异问题,不妨对照这篇文章检查一遍,大概率能找到答案。