MyBatis的动态查询配置

前言

记录一些对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如果在表达式后面多出逗号,就自动帮我去掉。

你可能感兴趣的:(mybatis)