聊聊mybatis的动态sql

作者: Java面试官 | 来源:发表于2016-12-02 21:40 被阅读277次

    说在前面

    最近一直忙着做项目,都没什么时间写写博客,真是不开心。
    今天想聊聊Mybatis的动态sql,采用的还是老形式,通过源码分析:


    MyBatis中用于实现动态SQL的元素主要有:

    • if
    • choose
    • where
    • trim
    • set
    • foreach

    我们先从简单的 if 说起:

    <select id="getTotalRows" resultType="java.lang.Integer"
        parameterType="java.lang.String">
        SELECT * FROM mvc_user_info u where u.user_name = 'lixifan'
            <if test="trueName != null and trueName != ''">
                AND u.true_name LIKE CONCAT('%',#{trueName},'%')
            </if>
            <if test="mail != null and mail != ''">
                AND u.mail LIKE CONCAT('%',#{mail},'%')
            </if>
    </select>
    这几行代码的意思其实就是如果你传递了trueName,那么就要满足条件trueName = #{trueName},如果传递了mail,那么就要满足mail = #{mail},这种情况可以用于两种应用场景即只传trueName查出数据和只传mail 查出数据。我在开发中有多次使用这种情况,甚至有一次性将整个对象的数据成员都用if进行判断,通过这种方式来提高开发的速率。
    

    看完上面那个if的用法,很多人应该会想如何轻易做到只需满足一种条件即可的,比如java的switch,别急,现在聊聊choose咯:

    <select id="chooseTest" parameterType="Blog" resultType="Blog">  
    select * from mvc_user_info u where u.user_name = 'lixifan'
    <choose>  
        <when test="trueName != null">  
            and u.true_name = #{trueName }  
        </when>  
        <when test="mail != null">  
            and u.mail = #{mail }  
        </when>  
        <otherwise>  
            and age= "22"  
        </otherwise>  
    </choose>  
    

    </select>
    看到了吗,其实choose元素相当于java的switch语句,而when其实就相当于case,otherwise就是default,具体用法也是跟switch一样的啦,我就不多说了!


    嗯,现在看看where

    <select id="getTotalRows" resultType="java.lang.Integer"
        parameterType="java.lang.String">
        SELECT count(*) FROM mvc_user_info u LEFT JOIN mvc_dept_info d ON
        u.dept_id = d.dept_id
        <where>
            <if test="trueName != null and trueName != ''">
                AND u.true_name LIKE CONCAT('%',#{trueName},'%')
            </if>
            <if test="mail != null and mail != ''">
                AND u.mail LIKE CONCAT('%',#{mail},'%')
            </if>
            <if test="userLevel != null and userLevel != ''">
                AND u.user_level = #{userLevel}
            </if>
            <if test="deptNo != null and deptNo != ''">
                AND d.dept_no LIKE CONCAT('',#{deptNo},'%')
            </if>
        </where>
    </select>
    

    where元素的作用就是在写入where元素的地方插入一个where,而最大的功效应该是:(智能处理)

    • 如果所有的条件都不满足那么MyBatis就会查出所有的记录
    • 如果输出后是and 开头的,MyBatis会把第一个and忽略
    • 在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上

    聊聊trim

    <insert id="saveUser" parameterType="cn.springmvc.model.UserInfo">
        INSERT INTO mvc_user_info
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userName != null">
                user_name,
            </if>
            <if test="trueName != null">
                true_name,
            </if>
        </trim>
        VALUES
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userName != null">
                #{userName, jdbcType=VARCHAR},
            </if>
            <if test="trueName != null">
                #{trueName, jdbcType=VARCHAR},
            </if>
        </trim>
    </insert>
    

    先说说几个属性:
    prefix:加上前缀
    suffix:加上后缀
    suffixOverrides:将尾部的指定内容覆盖掉
    prefixOverrides:将首部的指定内容覆盖掉
    而结合上面的源码来说就是:
    构建成 INSERT INTO mvc_user_info(xx,yy) values(aa,bb);


    现在聊聊set

    <update id="test" parameterType="Blog">  
    update t_blog  
    <set>  
        <if test="title != null">  
            title = #{title},  
        </if>  
        <if test="content != null">  
            content = #{content},  
        </if>  
        <if test="owner != null">  
            owner = #{owner}  
        </if>  
    </set>  
    where id = #{id}  
    

    </update>
    set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。


    最后一个foreach了哈

    foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
    foreach元素的属性主要有item,index,collection,open,separator,close。
    item表示集合中每一个元素进行迭代时的别名;
    index指定一个名字,用于表示在迭代过程中,每次迭代到的位置;
    open表示该语句以什么开始;
    separator表示在每次进行迭代之间以什么符号作为分隔符;
    close表示以什么结束;
    实例如下:

    <delete id="deleteUser" parameterType="String">
        DELETE FROM mvc_user_info WHERE user_id IN
        <foreach collection="array" item="idItem" open="(" separator=","
            close=")">
            #{idItem}
        </foreach>
    </delete>
    

    Note:发布的这些文章全都是自己边学边总结的,难免有纰漏,如果发现有不足的地方,希望可以指出来,一起学习咯,么么哒。
    开源爱好者,相信开源的力量必将改变世界:
    github: https://github.com/wiatingpub
      osc  : https://git.oschina.net/xi_fan

    相关文章

      网友评论

        本文标题:聊聊mybatis的动态sql

        本文链接:https://www.haomeiwen.com/subject/txqqmttx.html