✅ 问题简述
你定义了一个 MyBatis 接口方法:
Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
并且在 XML 中写了对应的 SQL:
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
</where>
order by create_time desc
</select>
问题是:XML 中 #{name}
是怎么获取到的?MyBatis 是如何知道你传入了一个 EmployeePageQueryDTO
并能访问它的 name
字段?
✅ 答案
MyBatis 会自动解析你方法参数对象的属性,将其字段暴露为参数映射上下文中的变量。
🔧 具体解释
当你传入一个 POJO(普通 Java 对象) 类型参数,MyBatis 会使用 Java 的 反射机制 读取它的 getter 方法,将其字段作为上下文变量供 SQL 使用。
所以你可以直接在 <if>
或 #{}
中这样使用:
<if test="name != null"> ... </if>
这其实相当于:
employeePageQueryDTO.getName()
✅ MyBatis 参数映射机制简述
方法参数形式 | XML 中访问方式 | 说明 |
---|---|---|
只有一个普通对象参数 | #{属性名} / test="属性名 != null" |
MyBatis 会将对象“解包”,字段直接可用 |
多个参数 | 需使用 @Param("xxx") 或用 param1 、param2 访问 |
否则访问不到 |
Map 参数 | #{key} |
可直接使用 key |
基本类型参数(如 int , String ) |
#{param1} (或用 @Param("name") ) |
推荐使用 @Param 显式命名 |
✅ 示例:你的场景等价于这样
EmployeePageQueryDTO dto = new EmployeePageQueryDTO();
dto.setName("张三");
pageQuery(dto);
在执行 XML SQL 时,#{name}
会变成:
'%张三%'
MyBatis 是通过调用 dto.getName()
得到的。
⚠️ 注意事项
如果你的字段是嵌套的,比如:
public class QueryDTO {
private User user;
}
然后你要访问 user.name
,那就必须:
<if test="user != null and user.name != null">
and name = #{user.name}
</if>
✅ 总结一句话
是的,MyBatis 会自动解析你传入的 employeePageQueryDTO
,并将其字段(通过 getter)暴露到 SQL 中,允许你在 XML 中直接用 #{name}
这样的形式访问。
如果你还有多个参数、嵌套字段、或者希望统一规范访问,也可以使用 @Param("xxx")
显式命名参数。