什么样是动态SQL

MyBatis的2个强大特性之七日常是它的动态SQL能力。假如你有利用JDBC或别的一般框架的阅历,你就知晓条件串联SQL字符串在协同是多么地忧伤,确认保证不能忘了空格可能在列表的末梢的简易逗号,动态SQL能够彻底处理那种忧伤。

常常接纳动态SQL不恐怕是单身的一片段,MyBatis当然使用一种强大的动态SQL语言来改良那种意况,那种语言能够被用在任意映射的SQL语句中。

动态SQL成分和采用JSTL或别的相似的依照XML的文件处理器相似,在MyBatis此前的本子中,有许多成分须求通晓,MyBatis三大满世界升高了它们,未来用不到原来3/6的要素就能干活了,MyBatis选用成效强大的基于OGNL的表明式来清除其余因素。

OK,介绍就到那时候,下边来进入动态SQL的上学吧。

 

if

在动态SQL中所做的最通用的事情正是带有部分where子句的尺度,比如:

<select id="selectInCondition" parameterType="student" resultType="student">
    select * from student where studentId > #{studentId}
    <if test="studentName != null">
        and studentName = #{studentName};
    </if>
</select>

切切实实落实不写了,那么1旦自身那样调用:

List<Student> list = StudentOperator.getInstance().selectInCondition(0, "Jack", 0, null);

询问的正是studentId>0且studentName=”杰克”的拥有学生消息,借使换1种调用方式:

List<Student> list = StudentOperator.getInstance().selectInCondition(0, null, 0, null);

那正是说查询的就是studentId>0的享有学生音信。

三个where子句也是平等的,比如:

 

<select id="selectInCondition" parameterType="student" resultType="student">
    <![CDATA[
        select * from student where studentId > #{studentId}
    ]]>
    <if test="studentName != null and studentName != 'Jack' ">
        and studentName = #{studentName}
    </if>
    <if test="studentAge != 0">
        and studentAge = #{studentAge};
    </if>
</select>

 

瞩目一下,能用”<![CDATA[ …
]]>”尽量照旧用,不过只包动态SQL外的内容。

别的,test里面能够看清字符串、整型、浮点型,大胆地写评定圭臬吧。尽管属性是复合类型,则能够动用A.B的措施去赢得复合类型中的属性来开始展览相比。

 

choose、when、otherwise

突发性我们不想选拔具有的采取条件,相反大家想选拔过多状态下的1种。和Java中的switch…case…类似,MyBasit提供choose成分。

上面包车型客车例子是二种if判断都也许存在,接下去使用choose、when、other做壹些修改:

<select id=”selectInCondition” parameterType=”student”
resultType=”student”>
    <![CDATA[
        select * from student where studentId > #{studentId}
    ]]>
    <choose>
        <when test=”studentName != null”>
            and studentName = #{studentName};
        </when>
        <when test=”studentAge != 0″>
            and studentAge = #{studentAge};
        </when>
        <otherwise>
            or 1 = 1;
        </otherwise>
    </choose>
</select>

 

四个when只可以满足一个,都不满意则走other。依然小心一下那里的”<![CDATA[
… ]]>”,不得以包围整个讲话。

 

trim、where、set

先是个例子已经示例了if的用法,可是那种用法有个毛病—-动态SQL外必须有where子句。

如何意思,因为许多时候大家须要where前边的子句都动态变化,而不是优先有二个where,那样就不符合规律,比如说:

<select id=”selectInCondition” parameterType=”student”
resultType=”student”>
    <![CDATA[
        select * from student where
    ]]>
    <if test=”studentName != null and studentName != ‘Jack’ “>
        and studentName = #{studentName}
    </if>
    <if test=”studentAge != 0″>
        and studentAge = #{studentAge};
    </if>
</select>

 

只要全数条件都不合营,那么生成的SQL语句将是:

select * from student where

那将招致查询失败。就算只知足3个查询条件照旧不符合规律,比如满足studentName这一个吧,生成的SQL语句将是:

select * from student where and studentName = #{studentName};

以此查询也会失利。

化解办法也有,贰个得益的章程是用where 1 = 一的章程,即:

<select id=”selectInCondition” parameterType=”student”
resultType=”student”>
    <![CDATA[
        select * from student where 1 = 1
    ]]>
    <if test=”studentName != null and studentName != ‘Jack’ “>
        and studentName = #{studentName}
    </if>
    <if test=”studentAge != 0″>
        and studentAge = #{studentAge};
    </if>
</select>

 

因为”一 =
1″永远满意,所以一定于给where加了一层true而已,此时动态SQL生成怎么着where衡量准则正是怎么着。

此外1个化解办法是接纳MyBatis中的1个不难易行处理方式,那在十分之九动静下都会有用并且。而在无法使用的地方,能够以自定义格局处理。加上三个简短的改观,全数的业务都会顺遂进行:

<select id=”selectInCondition” parameterType=”student”
resultType=”student”>
    <![CDATA[
        select * from student
    ]]>
    <where>
        <if test=”studentName != null and studentName != ‘Jack’
“>
            and studentName = #{studentName}
        </if>
        <if test=”studentAge != 0″>
            and studentAge = #{studentAge};
        </if>
    </where>
</select>

 

where成分知道假若由被含有的号子重回任意内容,就只是插入where。而且,若是以”and”或”or”初始的内容,那么就会跳过where不插入。

如若where成分未有做出你想要的,那么能够应用trim成分来自定义。比如,和where成分相等的trim成分是:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
…
</trim>

即:

 

<select id="selectInCondition" parameterType="student" resultType="student">
    select * from student
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        <if test="studentName != null and studentName != 'Jack' ">
            and studentName = #{studentName}
        </if>
        <if test="studentAge != 0">
            and studentAge = #{studentAge};
        </if>
    </trim>
</select>

 

特意要留意,prefixOverrides中的空白也是很重点的

末尾三个小内容,和动态更新语句相似的消除方案是set。set元素可以被用来动态蕴涵更新的列,而不分包不需求更新的。比如:

<update id=”updateStudentAgeById” parameterType=”Student”>
    <!–update student set studentAge = #{studentAge} where
        studentId = #{studentId}; –>
    <![CDATA[
        update student
    ]]>
    <set>
        <if test=”studentAge != 0″>studentAge =
#{studentAge}</if>
    </set>
    where studentId = #{studentId}
</update>

 

能够对照一下,注释掉的是原update语句,未有注释的是投入动态SQL之后的言辞。

此地,set成分会动态前置set关键字,而且也会消除任意非亲非故的逗号。要是你对和那里对等的trim成分好奇,它看起来是那般的:

<trim prefix="SET" prefixOverrides=",">
…
</trim>

那种时候大家附加一个后缀,同时也增大学一年级个前缀。

 

foreach

其余一个动态SQL通用的供给操作时迭代多少个相会,常常是营造在in条件中的。比如(上边的例证都以自身在投机电脑上跑通过的事例,那一个例子就径直复制MyBatis官方文书档案上的剧情了):

<select id=”selectPostIn” resultType=”domain.blog.Post”>
    <![CDATA[
        SELECT * FROM POST P WHERE ID in
    ]]>
    <foreach item=”item” index=”index” collection=”list”
        open=”(” separator=”,” close=”)”>
        #{item}
    </foreach>
</select>

 

foreach是非凡强大的,它同意你钦赐多少个相会,注解集合项和目录变量,它们得以用在要素体内。他也允许你钦定开放和倒闭字符串,在迭代之内放置分隔符。那些成分是很智能的,它不会偶尔地附加多余的分隔符。

相关文章

网站地图xml地图