_parameter 是一个特殊的变量名,用于引用传递给 SQL 映射语句的参数对象。

在 Mapper 接口的方法中定义了参数且没有使用 @Param 注解指定名称时,并希望在对应的 XML 映射文件中使用这些参数时,可以使用 _parameter 来引用。主要出现在动态 SQL 构建过程中,比如 <if><choose><when><otherwise> 等标签内,用来判断或使用传入的参数。

像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
<select id="queryUser" parameterType="cn.z2huo.demo.model.dataobject.user.UserDO"
resultType="cn.z2huo.demo.model.dataobject.user.UserDO">
select * from z2huo_user
<where>
<if test="_parameter.userCode != null and _parameter.userCode != ''">
and user_code = #{_parameter.userCode}
</if>
<if test="_parameter.userName != null and _parameter.userName != ''">
and user_name = #{_parameter.userName}
</if>
</where>
</select>

另外 Mapper 接口中方法如下:

1
List<UserDO> queryUser(UserDO userDO);

虽然 _parameter 提供了一种方式来访问整个参数对象,但在实际开发中,直接使用具体的参数名(如上述例子中的 nameage)更加直观和常用。只有在需要对整个参数对象进行操作或判断时,才会考虑使用 _parameter

比如上面的 XML 文件可修改为如下,因为不需要对 userDO 参数对象做单独判断:

1
2
3
4
5
6
7
8
9
10
11
12
<select id="queryUser" parameterType="cn.z2huo.demo.model.dataobject.user.UserDO"
resultType="cn.z2huo.demo.model.dataobject.user.UserDO">
select * from z2huo_user
<where>
<if test="userCode != null and userCode != ''">
and user_code = #{userCode}
</if>
<if test="userName != null and userName != ''">
and user_name = #{userName}
</if>
</where>
</select>

需要对 Mapper 的参数做单独的判断时,<if> 标签中可能存在需要以参数不为 null 为前提的语句,所以提前做出 _parameter != null 判断:

1
2
3
4
5
6
7
8
9
<select id="queryUser2" parameterType="cn.z2huo.demo.model.dataobject.user.UserDO"
resultType="cn.z2huo.demo.model.dataobject.user.UserDO">
select * from z2huo_user
<where>
<if test="_parameter != null">
......
</if>
</where>
</select>

感觉这个东西,实际用到的情况不多。_parameter 是在 Mybatis Generator 生成的 Mapper XML 文件中看到的,比如生成的文件中的 selectByExample 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<select id="selectByExample" parameterType="cn.z2huo.usercenter.example.permission.PermissionDOExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List"/>
from u_c_permission
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>

上面的 Example_Where_Clause SQL 片段内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>

也就是在 <foreach> 前判断 selectByExample 方法入参是否为 null,防止 <foreach> 报错。

另外对于 <foreach> 标签来说 _parameter 不为 null 并不足够,oredCriteria 列表为 null 也不可行,而针对这一点 Mybatis Generator 生成的 Example 类在新建对象时会对 oredCriteria 进行了初始化:

1
2
3
4
5
6
7
8
9
public class PermissionDOExample {

protected List<Criteria> oredCriteria;

public PermissionDOExample() {
oredCriteria = new ArrayList<>();
}

}

相关链接

OB tags

#MyBatis