mybatis-config.xml 是 mybatis 启动必需的核心配置文件,定义数据源、环境、映射等关键行为,标签顺序必须严格遵循 properties→settings→typealiases→typehandlers→objectfactory→plugins→environments→databaseidprovider→mappers,否则解析失败。

mybatis-config.xml 是 MyBatis 的核心全局配置文件,它不是可有可无的“辅助配置”,而是框架启动时必须加载的 XML 入口——没有它,MyBatis 无法知道数据库怎么连、事务怎么管、SQL 映射在哪、日志怎么打。
它本质是一份「运行时契约」:告诉 MyBatis 该用什么数据源、默认走哪个环境、SQL 结果怎么映射、哪些类可以简写别名、是否开启驼峰转换……所有影响行为的关键开关,都集中在这里定义。
为什么必须严格按顺序写标签?
MyBatis 解析 mybatis-config.xml 时会校验 XML 元素顺序,顺序错一位(比如把 <settings></settings> 放在 <properties></properties> 前面),启动直接抛异常:org.xml.sax.SAXParseException: The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。
正确顺序(必须死记)是:
<properties></properties><settings></settings><typealiases></typealiases><typehandlers></typehandlers><objectfactory></objectfactory><plugins></plugins><environments></environments><databaseidprovider></databaseidprovider><mappers></mappers>
常见错误:把 <mappers></mappers> 提前到 <settings></settings> 前面,或漏掉 <properties></properties> 却在 <environments></environments> 里用了 ${xxx} 占位符——此时 MyBatis 还没读到属性定义,自然报 Property not found。
如何用 db.properties 解耦数据库连接信息?
硬编码数据库地址、账号密码在 XML 里,既不安全也不利于多环境切换。标准做法是抽离为外部 db.properties 文件,并通过 <properties resource="db.properties"></properties> 引入。
操作步骤:
- 在
src/main/resources/下新建db.properties:
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/myapp?useSSL=false&useUnicode=true&characterEncoding=UTF-8 username=root password=123456
- 在
mybatis-config.xml顶部(<configuration></configuration>内第一位置)写:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<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>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>⚠️ 注意:resource 路径是相对于类路径(classpath)的,不能写成 ./db.properties 或绝对路径;若提示找不到文件,请确认该文件确实在编译后出现在 target/classes/ 目录下。
哪些配置项真正影响日常开发?
不必背全 30+ 个 <setting></setting>,但以下 4 个几乎每个项目都要显式设置:
-
logImpl:指定日志实现,否则看不到 SQL 打印。常用值:LOG4J、SLF4J、STDOUT_LOGGING(开发调试用) -
mapUnderscoreToCamelCase:设为true后,数据库字段user_name自动映射到 Java 属性userName,省去手写<resultmap></resultmap> -
lazyLoadingEnabled:启用懒加载,配合<association></association>/<collection></collection>避免 N+1 查询(但需搭配aggressiveLazyLoading=false才精准) -
cacheEnabled:全局二级缓存开关,默认true,但若没配<cache></cache>在 Mapper XML 中,实际无效
示例写法:
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
别名和 Mapper 注册最容易出错的点
<typealiases></typealiases> 不是为了“好看”,而是避免在 XML 里反复写一长串全限定类名,比如 com.example.entity.User。
- 单个别名(适合少量实体):
<typealias type="com.example.entity.User" alias="User"></typealias> - 批量扫包(推荐):
<package name="com.example.entity"></package>→ 所有该包下类自动以类名小写为别名(User对应com.example.entity.User)
<mappers></mappers> 是让 MyBatis “看见”你的 SQL 映射规则的地方。注意三类注册方式互斥且有约束:
-
<mapper resource="UserMapper.xml"></mapper>:XML 文件必须在 classpath 下,路径是相对于 classpath 的(如文件在src/main/resources/mapper/UserMapper.xml,这里就写mapper/UserMapper.xml) -
<mapper class="com.example.dao.UserMapper"></mapper>:接口必须与 XML 的namespace完全一致,且 XML 必须同名同包(或手动配置路径) -
<package name="com.example.dao"></package>:会自动扫描该包下所有接口,但要求对应 XML 必须在 classpath 同路径下,例如接口com.example.dao.UserMapper→ XML 必须在mapper/com/example/dao/UserMapper.xml或用注解代替
最常踩的坑:ClassNotFoundException 或 Invalid bound statement (not found),90% 是因为 <mappers></mappers> 里写的路径不对,或者 XML 文件没被 Maven 编译进 target/classes(检查 pom.xml 是否遗漏 <resources></resources> 配置)。
配置本身不难,难的是每一步都依赖上一步的正确性:属性没加载 → 数据源初始化失败;环境没指定 → SqlSessionFactoryBuilder 构建时报空指针;Mapper 没注册 → session.getMapper(UserMapper.class) 返回 null。建议第一次搭建时,用最简结构(单环境 + 单 mapper + STDOUT_LOGGING)跑通再逐步加配置。










