好家伙是动态SQL

MyBatis的一个精锐特性有通常是其的动态SQL能力。如果您出采取JDBC或任何一般框架的经历,你便清楚条件串联SQL字符串在协同是何等地痛,确保无可知忘怀了空格或在列表的最后之简约逗号,动态SQL可以彻底处理这种痛苦。

平凡用动态SQL不可能是独的相同有的,MyBatis当然使用相同种强大的动态SQL语言来改进这种情景,这种语言可以为用当任意映射的SQL语句被。

动态SQL元素和行使JSTL或外相似的基于XML的文本处理器相似,在MyBatis之前的版中,有过多因素用了解,MyBatis3死全球提升了其,现在就此不至原来一半之素即可知干活了,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>

切实落实无写了,那么要本身这样调用:

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

询问的即使是studentId>0且studentName=”Jack”的兼具学员信息,如果换一种调用方式:

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

有时我们不思量以拥有的运用条件,相反我们纪念选过多状态下的一致种植。和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

就将致查询失败。即使只有满足一个查询条件或来题目,比如满足studentName那个吧,生成的SQL语句以凡:

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

夫查询也会砸。

解决办法也时有发生,一个得益的不二法门是用where 1 = 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 =
1″永远满足,所以一定给受where加了一致重合true而已,此时动态SQL生成什么where判断标准就是啊。

另外一个解决办法是使MyBatis中之一个简单易行处理方式,这在90%情况下还见面发生因此并且。而于非可知应用的地方,可以坐由定义方式处理。加上一个简便的变动,所有的事情都见面顺利进行:

<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地图