美文网首页
MyBatis学习笔记(五):动态SQL

MyBatis学习笔记(五):动态SQL

作者: 简单一点点 | 来源:发表于2019-01-02 16:49 被阅读2次

    传统的JDBC方法,在使用复杂SQL的时候经常需要拼接,不仅麻烦而且容易出错。MyBatisd的动态SQL技术可以通过几个标签组合出灵活的SQL语句,提高开发效率。

    if、test元素

    if元素用于判断语句,常与test元素配合使用。test元素用来判断真假,大部分情况用来判断非空。

    <select id="getHero" resultType="hero">
        select id, hero_name as heroName, hero_title as heroTitle, main_property as mainProperty,
        note from t_heroes where 1= 1 
        <if test="heroName != null and roleName != ''">
            and hero_name = #{heroName}
        </if>
    </select>
    

    choose、 when、 otherwise元素

    类似于JAVA中的switch,用于多条件选择语句。

    <select id="getHero" resultType="hero">
        select id, hero_name as heroName, hero_title as heroTitle, main_property as mainProperty,
        note from t_heroes where 1=1
        <choose> 
            <when test="heroName != null and heroName != ''">
                and hero_name = #{heroName}
            </when>
            <when test="heroTitle != null and heroName != ''">
                and hero_title = #{heroTitle}
            </when>
            <otherwise>
                note is not null
            </otherwise>
        </choose>
    </select>
    

    where、 trim、 set元素

    前面的where后面都加了1=1,这是因为如果不加语句会有语法问题(有可能where后面紧接着and)。where元素就可以处理这种情况。看下面的例子,表面上看只是多了一个标签,但实际上它后面出现and或or这些字段的时候,它知道如何处理。

    <select id="getHero" resultType="hero">
        select id, hero_name as heroName, hero_title as heroTitle, main_property as mainProperty,
        note from t_heroes
        <where> 
            <if test="heroName != null and heroName != ''">
                and hero_name = #{heroName}
            </if>
            <if test="heroTitle != null and heroName != ''">
                and hero_title = #{heroTitle}
            </if>
        </where>
    </select>
    

    trim标签也可以实现。下面的例子的意思是当where后面紧随and或者or的化,就去掉它们。

    <trim prefix="where" prefixOverrides="and|or">
        ...
    </trim>
    

    和where一样,set元素也是解决set语句的问题(有可能set后面紧接逗号)。

    <update id="updateHero" parameterType="hero">
       update t_heroes
        <set> 
            <if test="heroName != null and heroName != ''">
                hero_name = #{heroName},
            </if>
            <if test="heroTitle != null and heroName != ''">
                hero_title = #{heroTitle}
            </if>
        </set>
        where id = #{id}
    </update>
    

    同样,上面set语句中的逗号问题也可以使用trim解决。

    foreach元素

    foreach元素是一个循环语句,用来遍历集合,往往用于SQL中的in关键字。

    <select id="getHeroesById" resultType="hero">
        select id, hero_name as heroName, hero_title  as heroTitle, main_property as mainProperty,
            note from t_heroes where id in
        <foreach item="heroId" index="index" collection="idList" 
            open="(" separator="," close=")">
            #{heroId}
        </foreach>
    </select>
    

    foreach用法相对复杂,大概解释一下。

    • collection 传递进来的集合参数的名称。
    • item 循环中当前的元素。
    • index 当前元素在集合位置的下标。
    • open和close 以什么符号将这些集合中的元素包含起来。
    • separator 各个元素的间隔符。

    bind元素

    bind元素是通过OGNL表达式去自定义一个上下文变量。在进行模糊查询的时候,MySQL数据库会使用concat,与“%”和参数相连,Oracle数据库会使用连接符号“||”。有了bind元素,就不必使用数据库语言,增强了可移植性。

    <select id="getHero2" resultType="hero">
        <bind name="p_heroName" value="'%' + heroName +'%'" />
        <bind name="p_heroTitle" value="'%' + heroTitle +'%'" />
        select id, hero_name as heroName, hero_title as heroTitle, main_property as mainProperty,
        note from t_heroes where hero_name like p_heroName and hero_title like p_heroTtile
    </select>
    

    绑定2个新变量p_heroName和p_heroTitle,可以在SQL的其它地方使用。

    相关文章

      网友评论

          本文标题:MyBatis学习笔记(五):动态SQL

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