Mybatis:动态SQL
Mybatis动态SQL包含以下几种元素
if
判断语句:用于单条件分支判断
choose(when,otherwise)
相当于java里switch与case语句
trim(where,set)
辅助元素:处理SQL拼装问题
foreach
循环语句:在in语句等列举条件常用
虽然动态SQL的元素不多,但却能带来极大地方便,下面来演示一下使用
环境搭建参见我以前的博客,这里直接进入实战
SQL如下
CREATE TABLE t_role_db(
id INT AUTO_INCREMENT PRIMARY KEY,
note VARCHAR(32),
roleName VARCHAR(32)
);
使用动态SQL改装SQL语句(role是Role类的全限定类名的别名)
<!--简单的SQL,不使用if前-->
<select id="findByName" parameterType="string" resultType="role">
SELECT id,note,roleName FROM t_role_db WHERE NAME LIKE #{roleName}
</select>
这条SQL语句虽然可以实现功能,但是写死了,没有任何灵活性
使用改造该SQL
<select id="findByName" parameterType="string" resultType="role">
SELECT id,note,roleName FROM t_role_db WHERE 1=1
<if test="roleName != null and roleName != ''">
AND roleName LIKE #{roleName}
</if>
</select>
注意,这里有个坑!在启动的时候会报错(Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘roleName’ in ‘class java.lang.String’),这是因为Mybatis底层BoundSql处理parameterObject时会把参数当Map处理,类似(“1”,参数),(“2”,参数)…这样的map,把上面的SQL改成:
<select id="findByName" parameterType="string" resultType="role">
SELECT id,note,roleName FROM t_role_db WHERE 1=1
<if test="1 != null and 1 != ''">
AND roleName LIKE #{roleName}
</if>
</select>
即可运行,但更好的解决方案是在接口处加注解@Param(“键名”),就是把你的map改成(“键名”,参数)的类型
这样即可解决这个坑
虽然可以使用if进行判断了,但是上面的1=1令人很不爽,我们可以使用where来解决
<select id="findByName" parameterType="string" resultType="role">
SELECT id,note,roleName FROM t_role_db
<where>
<if test="roleName != null and roleName != ''">
roleName LIKE #{roleName}
</if>
</where>
</select>
现在我们需要实现模糊查询时还需要传%%,解决这个问题就需要bind制定一个上下文变量
理想最终生成的SQL:SELECT id,note,roleName FROM t_role_db WHERE roleName LIKE %参数%
使用动态SQL实现
<select id="findByName" parameterType="string" resultType="role">
SELECT id,note,roleName FROM t_role_db
<bind name="pattern_roleName" value="'%'+roleName+'%'"></bind>
<where>
<if test="roleName != null and roleName != ''">
roleName LIKE #{pattern_roleName}
</if>
</where>
</select>
set元素的使用:目标SQL UPDATE SET … WHERE …
<update id="updateRole" parametertype="role">
update t_role_db
<set>
<if test="roleName != null and roleName != ''">
roleName=#{roleName}
</if>
<if test="note != null and note != ''">
note=#{note}
</if>
</set>
<where>
<if test="roleName != null and roleName != ''">
roleName=#{roleName}
</if>
</where>
</update>
trim用于去除某一个特点字段前后的指定字符
如去除set后面的 ,
<trim prefix="SET" suffixOverrides=",">