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

MyBatis 多參數傳遞完整指南:@Param 註解 vs Map vs JavaBean

     編輯:Java 相關知識

前言

MyBatis Mapper 方法傳遞多個參數時,不能像單參數那樣直接用 _parameter 或屬性名訪問。本文系統梳理三種主流方案:**@Param 註解(推薦)**、**Map 封裝**、**JavaBean 封裝**,並對比優缺點與適用場景。

單參數回顧

<!-- Mapper 接口 -->
List<String> selectAirports(Boolean mapping);

<!-- XML -->
<select id="selectAirports" resultType="string" parameterType="boolean">
    SELECT ... <if test="_parameter == true">...</if>
</select>

單參數時,MyBatis 自動將參數綁定為 _parameter,也可直接用參數名(如 mapping)。

方案一:@Param 註解(官方推薦,最清晰)

Mapper 接口

public interface AirlineMapper {
    Airline selectEffectiveAirline(
        @Param("departureAirport") String departureAirport,
        @Param("arrivalAirport") String arrivalAirport,
        @Param("status") BigDecimal status
    );
}

XML 映射

<select id="selectEffectiveAirline" resultMap="BaseResultMap">
    SELECT <include refid="Base_Column_List"/>
    FROM USR_AIR_LINE
    <where>
        <if test="departureAirport != null">DEPARTURE_AIRPORT = #{departureAirport}</if>
        <if test="arrivalAirport != null">AND ARRIVAL_AIRPORT = #{arrivalAirport}</if>
        <if test="status != null">AND STATUS = #{status}</if>
    </where>
</select>

關鍵點

  • @Param 值即 XML 中的參數名,支持基本類型、POJO、集合
  • OGNL 表達式:#{paramName} 取值,test="paramName != null" 判斷**不加 #{}**
  • 參數順序無關,靠名稱匹配
  • 接口簽名清晰:調用方明確知道需要傳什麼參數

方案二:Map 封裝(靈活但隱式)

Mapper 接口

List<Airline> findAll(Map<String, Object> params);

Service 組裝 Map

public List<Airline> findAll(PageInfo page, Airline airline) {
    Map<String, Object> params = new HashMap<>();
    params.put("page", page);
    params.put("airline", airline);
    return airlineMapper.findAll(params);
}

XML 映射

<select id="findAll" resultMap="BaseResultMap" parameterType="java.util.Map">
    SELECT ...
    <where>
        <if test="airline.departureAirport != null">...</if>
    </where>
    <if test="page.sortName != null">
        ORDER BY ${fileders[page.sortName]} ${page.sortOrder}
    </if>
</select>

優缺點

  • ✅ 參數靈活,動態增減
  • ❌ 接口語義不清,調用方需查實現或文檔
  • ❌ 重構困難,易拼寫錯誤 Key
  • ❌ 類型安全差,運行時才報錯

方案三:JavaBean / POJO 封裝(類型安全)

參數對象

public class AirlineQuery {
    private String departureAirport;
    private String arrivalAirport;
    private BigDecimal status;
    private PageInfo page;
    // getter/setter
}

Mapper 接口

List<Airline> findAll(AirlineQuery query);

XML 映射

<select id="findAll" resultMap="BaseResultMap" parameterType="com.xxx.AirlineQuery">
    SELECT ...
    <where>
        <if test="departureAirport != null">...</if>
    </where>
</select>

優缺點

  • ✅ 類型安全,IDE 支持重構、查找引用
  • ✅ 語義清晰,自文檔化
  • ✅ 易擴展,添加字段不影響調用方
  • ⚠️ 需額外定義類,微增加代碼量

對比總結

維度@ParamMapJavaBean
類型安全✅ 高❌ 低✅ 高
接口清晰度✅ 高❌ 低✅ 高
參數靈活性中 (固定簽名)✅ 極高中 (需修改類)
重構友好✅❌✅
適用場景2-5 參數、穩定接口動態查詢、報表、舊系統複雜查詢、長期維護項目

進階技巧

1. 混合使用:@Param + POJO

List<User> search(@Param("keyword") String keyword, @Param("page") PageRequest page);

2. 集合參數自動綁定

// 接口
List<User> findByIds(@Param("ids") List<Long> ids);

// XML
WHERE id IN (<foreach collection="ids" item="id" separator=",">#{id}</foreach>)

3. 註解版 SQL (無 XML)

@Select("SELECT * FROM user WHERE name = #{name} AND age > #{age}")
User findByNameAndAge(@Param("name") String name, @Param("age") int age);

最佳實踐建議

  1. 新項目首選 @Param:平衡清晰度與開發效率
  2. 複雜查詢條件 ≥ 5 個:定義 Query POJO
  3. 動態報表/搜索:Map + 輸入驗證
  4. 禁用單參數隱式綁定:即使單參數也加 @Param,保持一致性
  5. 參數名規範:駝峰命名,與數據庫列名區分 (如 departureAirport vs DEPARTURE_AIRPORT)

總結

MyBatis 多參數傳遞本質是參數名綁定。**@Param 註解**通過顯式命名實現接口與 XML 解耦,是大多數場景的最優解。**JavaBean**適合複雜業務參數封裝,**Map**作為過渡或動態場景補充。統一團隊規範,避免混用導致維護混亂。

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