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

MyBatis 實戰總結:參數傳遞、結果映射、原生 SQL、SQL 片段複用完整指南

     編輯:Java 綜合教學

MyBatis 核心功能實戰速查手冊

1. 參數傳遞:三種方式靈活應對

1.1 多參數:索引/註解方式

Mapper 介面:

List queryList(String workerId, Integer topNum);

XML:

<select id="queryList" resultType="com.demo.RecordVo">
    SELECT ID id, WORKER_ID workerId, UPDATE_DATE updateDate
    FROM USER_RECORDS t
    WHERE t.WORKER_ID = #{0}
    LIMIT #{1}
</select>

#{0} 對應第一個參數,#{1} 對應第二個。簡單但可讀性較差。

1.2 Map/POJO 封裝(推薦,最常用)

Mapper 介面:

Integer queryCountByWorkerId(Map queryParam);

XML:

<select id="queryCountByWorkerId" parameterType="java.util.Map" resultType="java.lang.Integer">
    SELECT COUNT(1)
    FROM tableName F
    WHERE F.WORKER_ID = #{workerId}
</select>

Map key / POJO 屬性名直接對應 #{propertyName}。清晰、可維護、支援複雜查詢條件。

1.3 @Param 註解(單參數多值、介面不想改 POJO 時)

Mapper 介面:

Integer queryCountByWorkerId(@Param("workerId") String workerId);

XML 同 1.2。本質上 MyBatis 將其封裝為 Map。

2. 結果映射:兩種策略任君選

2.1 顯式 resultMap(字段名與屬性名不一致時必用)

<resultMap type="com.demo.DataModule" id="dataModule">
    <result column="ID" property="id" />
    <result column="CREATE_DATE" property="createDate" />
    <result column="WORKERID" property="workerId" />
    <result column="UPDATE_DATE" property="updateDate" />
    <result column="STATUS" property="status" />
</resultMap>

<select id="queryAll" resultMap="dataModule">
    SELECT ID, CREATE_DATE, WORKERID, UPDATE_DATE, STATUS FROM tableName
</select>

SQL 查詢欄位用資料庫原名,resultMap 負責映射轉換。

2.2 別名自動映射(字段名與屬性名一致或可用別名對齊)

<select id="queryAll" resultType="com.demo.DataModule">
    SELECT ID id, CREATE_DATE createDate, WORKERID workerId FROM tableName
</select>

SQL 別名必須精確匹配實體類屬性名(駝峰命名)。簡潔但要求嚴格命名規範。

3. 執行原生 SQL:動態場景的終極武器

適用於:動態建表、複雜報表、跨庫查詢、SQL 由前端/配置產生。

3.1 參數封裝

public class ParamVo {
    private String sql;
    // getter/setter
}

3.2 Mapper 介面

int executeCreateSql(ParamVo vo);           // DDL/DML
List> executeSelectSql(ParamVo vo); // 查詢

3.3 XML 關鍵:${} 而非 #{}

<update id="executeCreateSql">
    ${sql}
</update>

<select id="executeSelectSql" resultType="java.util.Map">
    ${sql}
</select>

警告:${} 為直接字串替換,**極高風險 SQL 注入**。
僅限可信內部系統、嚴格驗證 SQL 白名單、或唯讀查詢場景。生產環境極謹慎使用!

4. SQL 片段複用:消除重複、提升維護性

4.1 定義片段

<sql id="queryChild">
    FROM tableName1 F
    RIGHT JOIN tableName2 C ON F.WORKER_ID = C.WORKER_ID
    WHERE F.STATUS = 1 AND F.WORKER_ID = #{workerId}
    ORDER BY C.CREATE_DATE DESC
</sql>

4.2 引用片段

<select id="queryCountByWorkerId" parameterType="java.util.Map" resultType="java.lang.Integer">
    SELECT COUNT(1)
    <include refid="queryChild"/>
</select>

<select id="queryListByWorkerId" parameterType="java.util.Map" resultType="com.demo.RecordVo">
    SELECT ID id, WORKER_ID workerId, UPDATE_DATE updateDate, ...
    <include refid="queryChild"/>
</select>

適用場景:共同 WHERE 條件、JOIN 關聯、排序分頁、公共欄位選擇。

5. 進階技巧與避坑指南

技巧說明注意事項
#{ } vs ${ }#{} 預編譯參數化(安全),${} 字串替換(靈活但危險)99% 場景用 #{},${} 僅用於表名、欄位名、排序欄位等無法參數化處
resultType vs resultMapresultType 簡單自動映射,resultMap 複雜映射、關聯、嵌套一對多、多對一、嵌套結果必須用 resultMap
動態 SQL<if>, <choose>, <where>, <trim>, <foreach><where> 自動處理 AND/OR 前綴,<trim> 更靈活
分頁插件PageHelper、MyBatis-Plus 内建分頁物理分頁優於邏輯分頁,避免全量查詢
類型處理器自定義 TypeHandler 處理 Enum、JSON、加密欄位註冊於配置或 @MappedTypes

最佳實踐:
1. 統一使用 Map/POJO + resultMap 模式
2. 複雜查詢優先考慮 SQL 片段複用
3. 動態 SQL 善用 <where><trim> 避免語法錯誤
4. 原生 SQL 列為最後手段,務必做注入防護
5. 關鍵查詢加上註釋 /* +MAX_EXECUTION_TIME(1000) */ 防慢查詢

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