MyBatis通过 OGNL 来进行动态 SQL 的使用的。目前, 动态 SQL 支持以下几种标签:
if 标签
if 标签是我们最常使用的。在查询、删除、更新的时候很可能会使用到。必须结合 test 属性联合使用。
在 WHERE 条件中使用 if 标签
这是常见的一种现象, 我们在进行按条件查询的时候, 可能会有多种情况。
查询条件
根据输入的学生信息进行条件检索
- 当只输入用户名时, 使用用户名进行模糊检索;
- 当只输入性别时, 使用性别进行完全匹配
- 当用户名和性别都存在时,用这两个条件进行查询匹配查询
动态 SQL
/**
* 根据输入的学生信息进行条件检索
* 1. 当只输入用户名时, 使用用户名进行模糊检索;
* 2. 当只输入邮箱时, 使用性别进行完全匹配
* 3. 当用户名和性别都存在时, 用这两个条件进行查询匹配的用
* @param student
* @return
*/
List<Student> selectByStudentSelective(Student student);
sql
<select id="selectByStudentSelective" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student">
select
<include refid="Base_Column_List" />
from student
where 1=1
<if test="name != null and name !=''">
and name like concat('%', #{name}, '%')
</if>
<if test="sex != null">
and sex=#{sex}
</if>
</select>
利用where 1=1拼接sql语句
<if test="name != null and name !=''">
and name like concat('%', #{name}, '%')
</if>
<if test="sex != null">
and sex=#{sex}
</if>
if 标签的 test 属性值是一个符合 OGNL 的表达式, 表达式可以是 true 或 false。如果表达式返回的是数值, 则0为 false, 非 0 为 true;
在 UPDATE 更新列中使用 if 标签
接口方法
/**
* 更新非空属性
*/
int updateByPrimaryKeySelective(Student record);
对应的 SQL
<update id="updateByPrimaryKeySelective" parameterType="com.homejim.mybatis.entity.Student">
update student
<set>
<if test="name != null">
`name` = #{name,jdbcType=VARCHAR},
</if>
<if test="phone != null">
phone = #{phone,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="sex != null">
sex = #{sex,jdbcType=TINYINT},
</if>
<if test="locked != null">
locked = #{locked,jdbcType=TINYINT},
</if>
<if test="gmtCreated != null">
gmt_created = #{gmtCreated,jdbcType=TIMESTAMP},
</if>
<if test="gmtModified != null">
gmt_modified = #{gmtModified,jdbcType=TIMESTAMP},
</if>
</set>
where student_id = #{studentId,jdbcType=INTEGER}
在 INSERT 动态插入中使用 if 标签
动态SQL
接口方法
/**
* 非空字段才进行插入
*/
int insertSelective(Student record);
对应的SQL
<insert id="insertSelective" parameterType="com.homejim.mybatis.entity.Student">
insert into student
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="studentId != null">
student_id,
</if>
<if test="name != null">
`name`,
</if>
<if test="phone != null">
phone,
</if>
<if test="email != null">
email,
</if>
<if test="sex != null">
sex,
</if>
<if test="locked != null">
locked,
</if>
<if test="gmtCreated != null">
gmt_created,
</if>
<if test="gmtModified != null">
gmt_modified,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="studentId != null">
#{studentId,jdbcType=INTEGER},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="phone != null">
#{phone,jdbcType=VARCHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="sex != null">
#{sex,jdbcType=TINYINT},
</if>
<if test="locked != null">
#{locked,jdbcType=TINYINT},
</if>
<if test="gmtCreated != null">
#{gmtCreated,jdbcType=TIMESTAMP},
</if>
<if test="gmtModified != null">
#{gmtModified,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
choose 标签
choose when otherwise 标签可以现 if else 的逻辑。一个 choose 标签至少有一个 when, 最多一个otherwise。
假设 name 具有唯一性, 查询一个学生
- 当 studen_id 有值时, 使用 studen_id 进行查询;
- 当 studen_id 没有值时, 使用 name 进行查询;
- 否则返回空
- 动态SQL
接口方法
/**
* - 当 studen_id 有值时, 使用 studen_id 进行查询;
* - 当 studen_id 没有值时, 使用 name 进行查询;
* - 否则返回空
*/
Student selectByIdOrName(Student record);
对应的SQL
<select id="selectByIdOrName" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student">
select
<include refid="Base_Column_List" />
from student
where 1=1
<choose>
<when test="studentId != null">
and student_id=#{studentId}
</when>
<when test="name != null and name != ''">
and name=#{name}
</when>
<otherwise>
and 1=2
</otherwise>
</choose>
</select>
- 有 ID 则根据 ID 获取, 结果
- 没有 ID 则根据 name 获取
- 没有 ID 和 name, 返回 null