首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis SqlMapConfig.xml 完整配置指南:屬性、別名、類型處理器、環境、映射器加載順序詳解

     編輯:Java 相關知識

配置文件結構與加載順序 (嚴格按 DTD)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <!-- 1. 屬性 (最先解析,供後續引用) -->
  <properties resource="jdbc.properties" />
  <properties url="https://config-center/props" />
  <property name="custom.key" value="value" />

  <!-- 2. 全局設置 -->
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <setting name="cacheEnabled" value="true"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
    <setting name="multipleResultSetsEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>
    <setting name="useGeneratedKeys" value="true"/>
    <setting name="autoMappingBehavior" value="PARTIAL"/>
    <setting name="defaultExecutorType" value="REUSE"/>
    <setting name="defaultStatementTimeout" value="30"/>
    <setting name="defaultFetchSize" value="100"/>
    <setting name="safeRowBoundsEnabled" value="false"/>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <setting name="localCacheScope" value="SESSION"/>
    <setting name="jdbcTypeForNull" value="OTHER"/>
    <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
  </settings>

  <!-- 3. 類型別名 -->
  <typeAliases>
    <!-- 單個 -->
    <typeAlias alias="User" type="com.example.model.User"/>
    <!-- 批量掃描包 (別名默認類名首字母小寫) -->
    <package name="com.example.model"/>
    <package name="com.example.dto"/>
  </typeAliases>

  <!-- 4. 類型處理器 -->
  <typeHandlers>
    <!-- 單個註冊 -->
    <typeHandler handler="com.example.handler.JsonTypeHandler" javaType="com.example.model.JsonData"/>
    <!-- 批量掃描 -->
    <package name="com.example.handler"/>
  </typeHandlers>

  <!-- 5. 對象工廠/插件/其他 -->
  <objectFactory type="com.example.factory.CustomObjectFactory"/>
  <plugins>
    <plugin interceptor="com.example.plugin.PageInterceptor">
      <property name="dialect" value="mysql"/>
      <property name="pageSqlId" value=".*Page.*"/>
    </plugin>
  </plugins>

  <!-- 6. 環境 (多環境支持,default 指定當前) -->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <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="10"/>
        <property name="poolMaximumCheckoutTime" value="20000"/>
        <property name="poolTimeToWait" value="20000"/>
        <property name="poolPingEnabled" value="true"/>
        <property name="poolPingQuery" value="SELECT 1"/>
        <property name="poolPingConnectionsNotUsedFor" value="300000"/>
      </dataSource>
    </environment>
    <environment id="production">
      <transactionManager type="JDBC"/>
      <dataSource type="JNDI">
        <property name="data_source" value="java:comp/env/jdbc/myapp"/>
      </dataSource>
    </environment>
  </environments>

  <!-- 7. 映射器 (最後加載,依賴前面所有配置) -->
  <mappers>
    <!-- 資源路徑 (相對類路徑) -->
    <mapper resource="mapper/UserMapper.xml"/>
    <!-- URL -->
    <mapper url="file:///var/mappers/OrderMapper.xml"/>
    <!-- 接口類 (需同名 XML 在同目錄) -->
    <mapper class="com.example.mapper.UserMapper"/>
    <!-- 批量掃描包 (接口+XML同名同目錄) -->
    <package name="com.example.mapper"/>
  </mappers>
</configuration>

核心配置項深度解析

1. Properties 屬性加載優先級

  1. 在 <properties> 內部定義的 <property> (最低)
  2. resource 引用的文件 (類路徑)
  3. url 引用的遠程配置
  4. Java 代碼構建 SqlSessionFactory 時傳入的 Properties 參數 (最高,覆蓋前者)

最佳實踐:敏感配置 (密碼) 用環境變量/配置中心注入,jdbc.properties 僅存非敏感默認值。

2. Settings 關鍵開關速查

設置名默認值建議生產值說明
mapUnderscoreToCamelCasefalsetrue自動映射下劃線列名到駝峰屬性 (user_name → userName)
cacheEnabledtruetrue全局二級緩存開關
lazyLoadingEnabledfalsetrue開啟延遲加載 (關聯查詢按需加載)
aggressiveLazyLoadingtrue (3.4.1+ false)falsetrue 時調用任意 getter 觸發全量加載,false 僅調用目標關聯屬性觸發
multipleResultSetsEnabledtruetrue支持存儲過程多結果集
useColumnLabeltruetrue用列標籤而非列名 (兼容性更好)
useGeneratedKeysfalsetrueINSERT 後自動回填自增主鍵
autoMappingBehaviorPARTIALPARTIALFULL 會自動映射嵌套結果集,可能導致 N+1
defaultExecutorTypeSIMPLEREUSEREUSE 重用 PreparedStatement,批量操作性能更好
defaultStatementTimeout未設置 (無限)30 (秒)防止慢 SQL 佔用連接池
defaultFetchSize未設置 (驅動默認)100結果集分批獲取,減少內存壓力
safeRowBoundsEnabledfalsefalsetrue 允許 RowBounds 在嵌套查詢中工作 (性能差)
localCacheScopeSESSIONSESSIONSTATEMENT 會禁用一級緩存,僅用於特殊場景
jdbcTypeForNullOTHEROTHERnull 參數的 JDBC 類型,某些驅動需指定 (如 Oracle NULL -> NULL TYPE)

3. TypeAliases 批量掃描規則

  • <package name="com.example.model"/> 掃描包下所有類
  • 別名默認:**類名首字母小寫** (UserInfo → userInfo)
  • 同名類衝突:後掃描者覆蓋,建議加 @Alias("customName") 註解顯式指定
  • 內部類別名:Outer$Inner → outer$Inner (不推薦),請用靜態內部類或獨立類

4. TypeHandlers 自定義類型轉換

// 例: JSON 字符串 <-> JsonData 對象 (PostgreSQL jsonb / MySQL json)
@MappedTypes(JsonData.class)
@MappedJdbcTypes(JdbcType.VARCHAR) // 或 OTHER
public class JsonTypeHandler extends BaseTypeHandler {

    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JsonData parameter, JdbcType jdbcType) 
            throws SQLException {
        ps.setString(i, mapper.writeValueAsString(parameter));
    }

    @Override
    public JsonData getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        return json != null ? mapper.readValue(json, JsonData.class) : null;
    }

    @Override
    public JsonData getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getNullableResult(rs, rs.getMetaData().getColumnLabel(columnIndex));
    }

    @Override
    public JsonData getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getNullableResult(cs, cs.getMetaData().getColumnLabel(columnIndex));
    }
}

註冊:<typeHandler handler="com.example.handler.JsonTypeHandler"/> 或包掃描。

5. Environments 多環境切換

  • <environments default="development"> 指定默認環境
  • 構建 SqlSessionFactory 時可覆蓋:new SqlSessionFactoryBuilder().build(inputStream, "production", props)
  • Spring 整合後:SqlSessionFactoryBean 完全接管,environments 失效,改用 Spring DataSource、PlatformTransactionManager、PropertyPlaceholderConfigurer。

6. Mappers 加載方式優先級建議

  1. 包掃描 <package name="com.example.mapper"/> (約定優於配置,接口+XML同名同目錄)
  2. 接口類 <mapper class="..."/> (單獨註冊,需 XML 同名同目錄)
  3. 資源路徑 <mapper resource="..."/> (舊項目、XML 與接口分離)
  4. URL <mapper url="..."/> (外部化映射文件)

Spring Boot 整合:零 XML 配置

# application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: true
    lazy-loading-enabled: true
    aggressive-lazy-loading: false
    default-executor-type: REUSE
    default-statement-timeout: 30
    default-fetch-size: 100
  type-aliases-package: com.example.model,com.example.dto
  type-handlers-package: com.example.handler
  mapper-locations: classpath*:mapper/**/*.xml  # 支持通配符、多模塊
  # 環境由 Spring DataSource 決定,無需 environments

避坑指南

現象原因解決
別名衝突導致映射錯誤不同包下同名類,默認別名相同加 @Alias("唯一名") 或改用全限定名
TypeHandler 不生效未註冊、或 javaType/jdbcType 不匹配檢查 @MappedTypes/@MappedJdbcTypes、包掃描路徑
延遲加載失效 / N+1 問題aggressiveLazyLoading=true、或未開啟 lazyLoadingEnabled設置 lazyLoadingEnabled=true, aggressiveLazyLoading=false
自增主鍵回填失敗useGeneratedKeys=false、或數據庫不支持 (Oracle 需 Sequence)MySQL/PostgreSQL/H2 開啟 true;Oracle 用 <selectKey>
PreparedStatement 洩漏defaultExecutorType=SIMPLE、長事務未提交改 REUSE、檢查連接池泄漏、設置 statementTimeout

總結

SqlMapConfig.xml 是 MyBatis 的「總控制台」。掌握**加載順序、Properties 優先級、Settings 開關矩陣、TypeAliases/Handlers 掃描規則、Environments 多環境、Mappers 加載策略**,即可駕馭複雜配置場景。**Spring Boot 項目建議棄用 XML,全面轉向 YAML 配置**,僅保留 Mapper XML 文件,簡潔且類型安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved