MyBatis 配置文件層級結構
configuration (根節點)
├── properties # 屬性佔位符
├── settings # 全局行為開關
├── typeAliases # 類型別名
├── typeHandlers # 類型處理器
├── objectFactory # 對象工廠
├── plugins # 插件攔截器
├── environments # 多環境配置
│ └── environment
│ ├── transactionManager
│ └── dataSource
└── mappers # 映射器註冊
核心配置節點詳細解析
1. properties —— 外部化配置
<properties resource="jdbc.properties">
<property name="username" value="dev_user"/>
<property name="password" value="secret"/>
</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>
resource:類路徑下屬性文件
url:文件系統路徑 file:///opt/config/jdbc.properties
- 優先級:外部傳入 > 內部
<property> > resource/url 文件
2. settings —— 關鍵行為開關 (20+ 項)
| 設定名 | 說明 | 可選值 | 默認 | 建議 |
| cacheEnabled | 全局開啟二級緩存 | true/false | true | 生產開啟 |
| lazyLoadingEnabled | 全局延遲加載 | true/false | false | 按需開啟 |
| aggressiveLazyLoading | 積極延遲加載 (調用任意方法觸發全量加載) | true/false | false | false 更精確 |
| multipleResultSetsEnabled | 支援多結果集 | true/false | true | 存儲過程需開啟 |
| useColumnLabel | 用列標簽代替列名 | true/false | true | true 兼容性好 |
| useGeneratedKeys | JDBC 自增主鍵回填 | true/false | false | XML 顯式配置優先 |
| autoMappingBehavior | 自動映射策略 | NONE/PARTIAL/FULL | PARTIAL | PARTIAL 平衡 |
| defaultExecutorType | 默認執行器 | SIMPLE/REUSE/BATCH | SIMPLE | SIMPLE |
| defaultStatementTimeout | 默認語句超時 (秒) | 整數 | 未設置 | 根據業務設置 (如 30) |
| mapUnderscoreToCamelCase | 下劃線轉駝峰 | true/false | false | true (強推) |
| localCacheScope | 一級緩存作用域 | SESSION/STATEMENT | SESSION | SESSION |
| jdbcTypeForNull | null 參數 JDBC 類型 | OTHER/VARCHAR/NULL | OTHER | Oracle 需 NULL |
3. typeAliases —— 簡化類型引用
<!-- 單個定義 -->
<typeAlias alias="User" type="com.example.entity.User"/>
<!-- 批量掃描包 (推薦) -->
<typeAliases>
<package name="com.example.entity"/>
</typeAliases>
<!-- 內置別名 (不區分大小寫) -->
_string, _int, _long, _double, _boolean, _byte, _short, _float
_integer, _long, _double, _bigdecimal, _date, _map, _list
4. typeHandlers —— 類型轉換器
<!-- 全局註冊 -->
<typeHandlers>
<typeHandler handler="com.example.handler.JsonTypeHandler"/>
<typeHandler handler="com.example.handler.EnumOrdinalTypeHandler"
javaType="com.example.enums.Status" jdbcType="INTEGER"/>
</typeHandlers>
<!-- 內置處理器 (部分) -->
BooleanTypeHandler, ByteArrayTypeHandler, DateTypeHandler,
EnumTypeHandler (name), EnumOrdinalTypeHandler (ordinal),
JsonTypeHandler (需 Jackson), InstantTypeHandler...
- 自定義實現
org.apache.ibatis.type.TypeHandler<T>
- 覆蓋順序:XML 顯式
jdbcType > 全局註冊 > 內置推斷
5. environments & dataSource —— 多環境數據源
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManager>
<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}"/>
<property name="poolMaximumActiveConnections" value="20"/>
<property name="poolMaximumIdleConnections" value="5"/>
<property name="poolMaximumCheckoutTime" value="20000"/>
</dataSource>
</environment>
<environment id="production">
<transactionManager type="MANAGED"/> -- 容器管理事務
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/prodDS"/>
</dataSource>
</environment>
</environments>
| dataSource 類型 | 說明 | 適用場景 |
| UNPOOLED | 每次新建連接 | 測試、極低併發 |
| POOLED | 內置連接池 | 中小應用、無外部池 |
| JNDI | 容器數據源 | 生產環境、應用服務器 |
| 自定義 | 實現 DataSourceFactory | HikariCP、Druid 等專業池 |
6. transactionManager —— 事務管理器
<!-- JDBC 事務 (默認) -->
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManager>
<!-- 容器管理事務 -->
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/> -- 容器負責關閉
</transactionManager>
7. mappers —— 映射器註冊 (四種方式)
<mappers>
<!-- 1. 資源路徑 (相對類路徑) -->
<mapper resource="mapper/UserMapper.xml"/>
<!-- 2. 類全限定名 (註解模式) -->
<mapper class="com.example.mapper.UserMapper"/>
<!-- 3. 包掃描 (推薦,需命名一致) -->
<package name="com.example.mapper"/>
<!-- 4. URL 絕對路徑 -->
<mapper url="file:///opt/mappers/UserMapper.xml"/>
</mappers>
映射器 XML 核心元素 (Mapper 級配置)
| 元素 | 用途 | 關鍵屬性 |
<cache> | 二級緩存配置 | eviction=LRU/FIFO/SOFT/WEAK, flushInterval(ms), size, readOnly |
<cache-ref> | 引用其他命名空間緩存 | namespace |
<resultMap> | 結果映射 (核心) | id, type, autoMapping, <id>, <result>, <association>, <collection> |
<sql> | 可復用 SQL 片段 | id, <include refid=""> |
<select/insert/update/delete> | CRUD 語句 | id, parameterType, resultType/resultMap, flushCache, useCache, timeout, fetchSize, statementType |
<parameterMap> | 參數映射 (舊版,棄用) | 建議用 parameterType + 內置類型處理器 |
resultMap 進階映射 (關鍵技能)
<resultMap id="userDetailMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="user_name"/>
<result property="email" column="email"/>
<!-- 一對一關聯 -->
<association property="profile" javaType="Profile">
<id property="id" column="profile_id"/>
<result property="avatar" column="avatar_url"/>
<result property="bio" column="bio"/>
</association>
<!-- 一對多集合 -->
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="amount" column="order_amount"/>
<result property="status" column="order_status"/>
</collection>
<!-- 嵌套 resultMap 復用 -->
<association property="department" resultMap="deptMap"/>
</resultMap>
動態 SQL 核心標籤 (OGNL 表達式)
| 標籤 | 用途 | 示例 |
<if> | 條件判斷 | <if test="username != null">AND username=#{username}</if> |
<choose/when/otherwise> | 多條件互斥 | 類似 switch-case |
<trim> | 前後綴處理 | <trim prefix="WHERE" suffixOverrides="AND|OR">...</trim> |
<where> | 智能 WHERE (自動去首 AND/OR) | <where><if...>...</where> |
<set> | 智能 SET (自動去尾逗號) | <set><if...>name=#{name},</if></set> |
<foreach> | 集合遍歷 | <foreach collection="list" item="id" separator=",">#{id}</foreach> |
<bind> | 定義變量 | <bind name="pattern" value="'%' + name + '%'"/> |
最佳實踐清單
- 啟用駝峰映射:
mapUnderscoreToCamelCase=true 消除 80% resultMap
- 統一使用 resultMap:複雜查詢、關聯對象、列名不同時,不依賴 resultType
- SQL 片段復用:
<sql id="cols">...</sql> + <include refid="cols"/>
- 參數傳遞:單參數直接用,多參數必加 @Param 或封裝 POJO/Map
- 超時設置:
defaultStatementTimeout=30 + 關鍵語句 timeout="10"
- 緩存策略:只讀參考表開啟
<cache readOnly="true"/>,寫多讀少表關閉
- 批量操作:
ExecutorType.BATCH + <foreach> 批量插入/更新
- 類型處理器:Enum 統一用
EnumOrdinalTypeHandler (存數值) 或自定義 JSON 處理器
總結
MyBatis XML 配置核心在於「settings 控制全局行為、typeAliases/Handlers 簡化類型系統、environments 隔離多環境、mappers 註冊映射器、resultMap 解決複雜映射、動態 SQL 構建靈活查詢」。掌握上述節點屬性、嵌套規則、優先級順序,配合「駝峰自動映射、resultMap 復用、SQL 片段抽取、動態 SQL 標籤」工程化實踐,即可構建可維護、高性能、多環境適配的持久層配置體系。