Mybatis 在mapper中如何传递多个参数?

MyBatis 传递多个参数的 5 种方式


1. 使用 @Param 注解(推荐)
// Mapper接口
User selectUser(@Param("username") String name, 
                @Param("age") int age);

// XML中使用
<select id="selectUser">
    SELECT * FROM user 
    WHERE username = #{username} AND age = #{age}
</select>

优点

  • 参数名清晰,可读性强

  • 支持基本类型和对象混合传参


2. 通过 Map 传递
// Java代码
Map<String, Object> params = new HashMap<>();
params.put("name", "张三");
params.put("age", 25);
mapper.selectByMap(params);

// XML中使用
<select id="selectByMap" parameterType="map">
    SELECT * FROM user 
    WHERE username = #{name} AND age = #{age}
</select>

适用场景

  • 动态条件查询

  • 参数数量不固定时


3. 使用 JavaBean 对象
// 定义参数对象
@Data
public class UserQuery {
    private String username;
    private Integer age;
}

// Mapper接口
List<User> selectByCondition(UserQuery query);

// XML中使用属性名直接引用
<select id="selectByCondition" parameterType="UserQuery">
    SELECT * FROM user 
    WHERE username = #{username} AND age = #{age}
</select>

优点

  • 参数结构化

  • 便于复用和扩展


4. 参数位置索引(不推荐)
// Mapper接口
User selectUser(String name, int age);

// XML中使用arg0/arg1或param1/param2
<select id="selectUser">
    SELECT * FROM user 
    WHERE username = #{arg0} AND age = #{param2}
</select>

缺点

  • 可读性差

  • 参数顺序变更会导致错误


5. 混合使用 @Param 和 JavaBean
// 接口方法
List<User> selectByMixed(@Param("page") PageInfo page,
                         @Param("query") UserQuery query);

// XML中使用
<select id="selectByMixed">
    SELECT * FROM user 
    WHERE username = #{query.username}
    AND age = #{query.age}
    LIMIT #{page.offset}, #{page.size}
</select>

适用场景

  • 分页查询+条件过滤组合

  • 需要复用参数对象时


各方案对比

方式可读性维护性适用场景
@Param 注解★★★★★★★★★☆参数少且明确
Map 传参★★☆☆☆★★☆☆☆动态参数
JavaBean★★★★☆★★★★★复杂条件查询
位置索引★☆☆☆☆★☆☆☆☆遗留代码兼容(不推荐新用)
混合模式★★★★☆★★★★☆需要组合参数时

最佳实践建议

  1. 2-3个参数:优先用@Param注解

  2. 4+个参数:封装为JavaBean

  3. 动态查询:Map 或 JavaBean + Builder模式

  4. 避免:使用arg0/param1这种隐式引用


特殊场景处理

批量操作传参
<update id="batchUpdate">
    UPDATE user SET status = #{status} 
    WHERE id IN 
    <foreach item="id" collection="ids" open="(" separator="," close=")">
        #{id}
    </foreach>
</update>

调用方式:

mapper.batchUpdate(@Param("status") int status, 
                   @Param("ids") List<Long> ids);

存储过程调用

<select id="callProcedure" statementType="CALLABLE">
    {call user_procedure(
        #{username,mode=IN},
        #{age,mode=IN},
        #{count,mode=OUT,jdbcType=INTEGER}
    )}
</select>

原理图解

通过合理选择传参方式,可以使代码既清晰又灵活。

MyBatis多参数传递的餐厅点餐比喻


1. @Param注解 → 自助点餐机
服务员.下单(
    @Param("主食") "牛肉面",
    @Param("饮料") "冰红茶"
);
  • 操作方式:每个菜品有明确分类按钮

  • 优势:厨房(MyBatis)清楚看到:

    • #{主食} → 牛肉面

    • #{饮料} → 冰红茶

  • 特点:适合点2-3个明确菜品


2. Map传参 → 手写便签条
Map 便签 = new HashMap();
便签.put("特辣", true);
便签.put("加料", "卤蛋");
服务员.下单(便签);
  • 特点

    • 厨师要自己解读潦草字迹(通过key取值)

    • 适合临时加特殊要求

  • 风险:字迹不清可能上错菜(key写错)


3. JavaBean对象 → 标准菜单
菜单 订单 = new 菜单();
订单.set主菜("宫保鸡丁");
订单.set甜点("杨枝甘露");
服务员.下单(订单);
  • 优势

    • 菜单有固定栏目(属性字段)

    • 厨师直接看栏目做菜(#{主菜}自动匹配)

  • 最佳实践:点全套套餐时(前菜+主菜+甜点+饮料)


4. 参数位置 → 神秘盲盒餐
服务员.下单("鱼香肉丝", "微辣");  // 第一个是菜?第二个是辣度?

厨房解读

炒#{param1},口味#{param2}
  • 灾难现场

    • 如果调换顺序:下单("重辣","水煮鱼") → 炒"重辣"?

  • 如同:让厨师蒙眼做菜

5. 混合模式 → 套餐+单点
服务员.下单(
    @Param("套餐") 情侣套餐,
    @Param("加菜") 单点小龙虾
);

厨房处理

准备#{套餐.主菜} 
额外制作#{加菜}
  • 适用场景:既有固定套餐又想额外加菜时

 

餐厅情景剧

顾客A:(用@Param)
"我要①#{主食}:饺子,②#{蘸料}:醋+辣椒"

顾客B:(用Map)
扔出一张便签:"多加香菜 不要蒜"

顾客C:(用JavaBean)
递上勾选好的标准菜单单

顾客D:(错误示范)
对着后厨大喊:"米饭 红烧肉"
(厨师困惑:到底是"红烧肉配米饭"还是"红烧肉味的米饭"?)


厨师长建议(最佳实践)

  1. 单人简餐:用点餐机(@Param)

    • 清晰高效:"#{菜名}:鱼香肉丝 #{辣度}:中辣 "

  2. 定制套餐:填菜单(JavaBean)

套餐.set主菜("牛排");
套餐.set配菜("土豆泥");

    3.特殊要求:附加便签(Map)

extras.put("忌口", "不要洋葱");

     4.千万别
       对着厨房乱喊(参数位置)
       "面条 牛肉" ← 这是要牛肉面?还是面条+牛肉两道菜?

为什么不要用参数位置?

就像去餐厅说:"给我第一个和第三个"
厨师内心OS:
"第一个是筷子?第三个是餐巾纸?
还是菜单上第一道和第三道菜?"

👉 永远给参数明确的名字

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EthanMilk

你的鼓励是我创作的最大动力谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值