记录一些对mybatis动态查询比较疑惑的地方
<select id="getLogonByCondition" parameterType="withoutspring.TestDTO" resultMap="logons">
select t.id as logon_id,
t.logonname,
t.password,
t.userid,
t1.id as user_id,
t1.displayname,
t1.logon
from logon t,user1 t1
<if test="userid != null">
where t.userid = #{userid}
</if>
<if test="displayname != null and displayname != '' ">
and t1.displayname = #{displayname}
</if>
</select>
这里使用了<if test=”displayname !=null and displayname!=''”> 来作非空的判断,如果不满足条件是不会连接and t1.dispalyname = #{displayname}这一句的。这里应该注意一下里面语法的写法,以及对空字符串的判断的写法
上面的代码会出现的问题就是如果第一个if都不满足,sql拼装后语法错误,少了where,多了and
改进代码
<select id="getLogonByCondition" parameterType="withoutspring.TestDTO" resultMap="logons">
select t.id as logon_id,
t.logonname,
t.password,
t.userid,
t1.id as user_id,
t1.displayname,
t1.logon
from logon t,user1 t1
where 1 = 1
<if test="userid != null">
and t.userid = #{userid}
</if>
<if test="displayname != null and displayname != '' ">
and t1.displayname = #{displayname}
</if>
</select>
这里面我加入了一个where 1 = 1 ,可以解决问题
myBatis还提供了其他写法
<where>标签来解决
<select id="getUser" parameterType="map" resultMap="userMap">
select id,
displayname
from user1
<where>
<if test="userid != null and userid != ''">
id = #{userid}
</if>
<if test="displayn != null and displayn != ''">
and displayname = #{displayn}
</if>
</where>
</select>
这里第一个if中不需要加and了,它如果满足条件的话是跟在where后面,第二个需要加and链接。myBatis帮你判断,在where后面如果第一个读到的是and ,那么就会自动去掉这个and
<trim>的写法
<select id="getUser" parameterType="map" resultMap="userMap">
select id,
displayname
from user1
<trim prefix="where" prefixOverrides="AND|OR">
<if test="userid != null and userid != ''">
and id = #{userid}
</if>
<if test="displayn != null and displayn != ''">
or displayname = #{displayn}
</if>
</trim>
</select>
这里使用了<trim>,这里prefix表示from后面需要连接的关键字,所以prefix前缀为where,但是prefixOverrides与suffixOverrides这两个属性表示什么意思? 上面讲过where后面,if条件不满足,会多出一些and,可以会出现where and displayname=’ ’ 这样的情况,这两个属性就是表明,如果多出来,就自动帮我去掉,prefixOverrides=‘AND | OR’指定如果多出and 或者 or的话,就去掉多出的这个关键字(and或者or都可以),当然如果写成prefixOverrides=‘AND’那么多出or,mybatis是不会负责去掉多出的or的。
还有一个困惑就是,为什么这里不用suffixOverrides? 这是因为and 和 or 都是在id = #{userid}和displayname = #{displayn}之前的,如果在后面,那就使用suffixOverrides
我们具体看看suffixOverrides如何使用
<update id="updateLogonWithCondition" parameterType="Map">
update logon
<trim prefix="set" suffixOverrides=",">
<if test="logonid != null and logonid != ''">
id = #{logonid},
</if>
<if test="displayname != null and displayname != ''">
logonname = #{displayname},
</if>
</trim>
<trim prefix="where" prefixOverrides="AND| OR">
<if test="myblog1 != null">logonname = #{myblog1}</if>
<if test="logonid1 != null">or id = #{logonid2}</if>
<if test="logonid1 != null">and id = #{logonid1};</if>
</trim>
</update>
在update中,我们可以用它提供的<set>表示,写法和<where>差不多,很智能,可以自动帮我们去掉多余的逗号,这里我使用<trim>
<trim prefix=”set” suffixOverrides=”,”>
正如上面说的,prefix是决定update logon后面跟什么关键字。因为id = #{logonid}, logonname = #{displayname}, 这里面可能会多余的逗号在表达式的后面,所以使用suffixOverrides=”,”告诉MyBatis如果在表达式后面多出逗号,就自动帮我去掉。