MyBatis 的 7 种传参方式详解
1. 顺序传递参数
通过方法参数的排列顺序进行传参,适用于多个简单类型参数。需注意在 XML 映射文件中必须按照参数顺序使用 #{arg0}、#{arg1} 或 #{param1}、#{param2} 等形式引用。
Controller 层示例:
@ApiOperation(value = "多个参数查询_匿名顺序传参")
@GetMapping("findByParams")
public ResultMsg findByParams(Short gender, String age) {
List result = employeeMapper.selectByGenderAndAge(gender, age);
return ResultMsg.getMsg(result);
}
Mapper 接口:
List<Employee> selectByGenderAndAge(Short gender, String age);
XML 映射配置(关键点:使用 param1、param2 按顺序引用):
<select id="selectByGenderAndAge" resultMap="BaseResultMap">
SELECT * FROM employee WHERE gender = #{param1} AND age = #{param2}
</select>
⚠️ 注意:参数索引从 param1 开始,param1 对应第一个参数,param2 对应第二个。
2. 使用 @Param 注解命名传参
为解决顺序传参可读性差的问题,可在 Mapper 接口中使用 @Param 注解为每个参数指定名称,使 XML 中可通过语义化名称访问。
Mapper 接口修改:
List<Employee> selectByGenderAndAge(@Param("gender") Short gender, @Param("age") String age);
XML 映射文件(推荐写法,清晰直观):
<select id="selectByGenderAndAge" resultMap="BaseResultMap">
SELECT * FROM employee WHERE gender = #{gender} AND age = #{age}
</select>
</select>
✅ 优势:代码可读性强,避免因参数顺序错误导致的 SQL 异常。
3. 使用 Map 传递多个参数
将多个参数封装成 Map<String, Object>,以键值对形式传递,适合参数较多或动态条件场景。
Controller 层封装 Map:
@ApiOperation(value = "多个参数查询_通过Map传递多个参数")
@GetMapping("findByMapParams")
public ResultMsg findByMapParams(Short gender, String age) {
Map<String, Object> params = new HashMap<>();
params.put("gender", gender);
params.put("age", age);
List result = employeeMapper.selectByMapParams(params);
return ResultMsg.getMsg(result);
}
XML 配置说明:
<select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map">
SELECT * FROM employee WHERE gender = #{gender} AND age = #{age}
</select>
✅ 说明:parameterType="map" 可省略,MyBatis 默认支持 Map 传参;通过 #{key} 直接取值。
4. 使用 Java Bean 对象传参
当参数结构固定且与实体类一致时,推荐使用 Java Bean,Controller 层通过 @RequestBody 接收 JSON 数据并直接传递给 Mapper。
Controller 层接收对象:
@ApiOperation(value = "多个参数查询_通过Java Bean传递多个参数")
@PostMapping("findByBeans")
public ResultMsg findByBeans(@RequestBody Employee employee) {
List result = employeeMapper.selectByBeans(employee);
return ResultMsg.getMsg(result);
}
XML 映射配置:
<select id="selectByBeans" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Employee">
SELECT * FROM employee WHERE gender = #{gender} AND age = #{age}
</select>
✅ 优势:结构清晰,自动映射属性,适合复杂对象查询。
5. 使用 JSON 对象直接传参
利用 JSONObject 接收任意结构的 JSON 数据,无需定义实体类,灵活性高,适用于动态查询场景。
Controller 层处理 JSON:
@ApiOperation(value = "多个参数查询_通过JSON传递多个参数")
@PostMapping("findByJSONObject")
public ResultMsg findByJSONObject(@RequestBody JSONObject params) {
List result = employeeMapper.findByJSONObject(params);
return ResultMsg.getMsg(result);
}
XML 配置与 Java Bean 类似:
<select id="findByJSONObject" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject">
SELECT * FROM employee WHERE gender = #{gender} AND age = #{age}
</select>
</select>
✅ 适用场景:快速开发、原型验证、字段不固定的接口。
6. 集合类型传参(List、Set、Array)
当需要根据集合进行 IN 查询时,可直接传递集合对象,配合 <foreach> 标签遍历处理。
Controller 层接收集合:
@ApiOperation(value = "多个参数查询_通过List、Set、Array传递多个参数")
@PostMapping("findByList")
public ResultMsg findByList(@RequestBody List<String> list) {
List result = employeeMapper.findByList(list);
return ResultMsg.getMsg(result);
}
XML 使用 <foreach> 构建 IN 条件:
<select id="findByList" resultMap="BaseResultMap">
SELECT * FROM employee WHERE age IN
<foreach collection="list" item="age" open="(" separator="," close=")">
#{age}
</foreach>
</select>
🔍 说明:
collection="list":默认参数名;item:循环变量名;open/close:包裹符号;separator:分隔符。
7. 对象中包含集合属性的传参
用于处理嵌套结构数据,如部门对象包含员工列表,可在对象内部使用集合,并在 XML 中通过 OGNL 表达式访问集合属性。
Controller 层接收复合对象:
@ApiOperation(value = "多个参数查询_对象+集合参数")
@PostMapping("findByDepartment")
public ResultMsg findByDepartment(@RequestBody Department department) {
List result = employeeMapper.findByDepartment(department);
return ResultMsg.getMsg(result);
}
Mapper 接口需配合 @Param 指定别名:
List<Employee> findByDepartment(@Param("department") Department department);
XML 中通过 OGNL 访问对象内集合:
<select id="findByDepartment" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Department">
SELECT * FROM employee
WHERE dept_id = #{department.id}
AND age IN
<foreach collection="department.employees" item="employee" open="(" separator="," close=")">
#{employee.age}
</foreach>
</select>
</select>
✅ 技巧:使用 @Param 可提升 OGNL 表达式的可读性和稳定性。
📌 总结建议:
- 参数少且简单 → 使用
@Param; - 参数多或结构固定 → 使用 Java Bean;
- 动态字段或快速开发 → 使用
Map或JSONObject; - 涉及
IN查询 → 必须使用<foreach>配合集合; - 复杂嵌套结构 → 结合
@Param与 OGNL 表达式访问对象属性。
合理选择传参方式,可显著提升代码可维护性与 SQL 安全性。