Java–MyBatis动态SQL;<if>,<where>,<foreach>标签;判断集合数组长度

  • Post author:
  • Post category:java


Mybatis主要使用标签

1、

<select></select>

对应注解@lSelect

2、

<update></update>

对应注解@Update

3、

<insert></insert>

对应注解@Insert

4、

<delete></delete>

对应注解@Delete

5、

<where></where>:

在某些条件根据入参有无决定是可使用以避免1=1这种写法,也会根据是否为where条件后第一个条件参数自动去除and

6、

<if></if>

:类似于java中的条件判断if,没有<else>标签

7、

<choose>

标签

<choose>
    <when></when>
    <otherwise></otherwise>
</choose>

8、

<foreach></foreach>

:可以对数组、Map或实现了Iterable接口(如List、Set)的对象遍历。可实现in、批量更新、批量插入等。

9、

<resultMap></resultMap>

:映射结果集

10、

<resultType></resultType>

:映射结果类型,可是java实体类或Map、List等类型

动态sql:

sql内容是变化的,可以根据条件获取到不同的sql语句,主要是where部分发生变化

动态sql的实现,使用的是mybatis提供的标签:<if> ,<where>,<foreach><if/>


一、<if>标签

<if>标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句

语法:<if test="判断java对象的属性值">

如下:

<select id="selectUsersIf" resultType="com.mycompany.domain.User">
        select user_id,user_name,email,age
        from user
        where 
        <!--
            select user_id,user_name,email,age from user where user_name = ? or age > ?
         -->
        <if test="userName != null and userName != ''">
            user_name = #{userName}
        </if>
        <if test="age > 0">
            or age > #{age}
        </if>
    </select>

这样会存在一个问题:如果 age 属性值为null,则会造成SQL语句错误,多带一个 “or” 字段,因此我们在where 条件语句后面加一个 恒成立等式,如 “1 = 1″,”user_id > 0″,如下格式:

<!-- if 标签
        <if test="使用java对象的属性值作为判断条件,语法:属性=XX值">
    -->
    <select id="selectUsersIf" resultType="com.mycompany.domain.User">
        select user_id,user_name,email,age
        from user
        where user_id > 0
        <!--
            select user_id,user_name,email,age from user where user_name = ? or age > ?
            select user_id,user_name,email,age from user where user_id > 0 and user_name = ? or age > ?
         -->
        <if test="userName != null and userName != ''">
            and user_name = #{userName}
        </if>
        <!--
            select user_id,user_name,email,age from user where or age > ?
        -->
        <if test="age > 0">
            or age > #{age}
        </if>
    </select>

标签的中存在一个问题:需要在 where 后手工添加 1=1 恒成立的子句;因为若 where 后 的所有<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,回导致SQL 出错


二、<where>标签

<where>标签用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增加一个where关键字,并去掉 if中多余的 and ,or等

使用<where/>标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句

注:

第一个<if/>标签中的 SQL 片断,可以不包含 and。但写上 and 也不错, 系统会将多出的 and 去掉

其它<if/>中 SQL 片断的 and 或者 or,必须写上;否则 SQL 语句将拼接出错

语法:<where> 其他动态 sql </where>

如下:

<!-- where标签
    <where> 用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增加一个where关键字,
            并去掉 if中多余的 and ,or等
        <where>
            <if>
            </if>
            ...
        </where>
    -->
    <select id="selectUsersWhere" resultType="com.mycompany.domain.User">
        <!-- select user_id,user_name,email,age
        from user -->
        <!-- select <include refid="selectUserOne" /> from user -->
        <include refid="selectUser" />
        <where>
            <if test="userName != null and userName != ''">
                user_name = #{userName}
            </if>
            <!--
                where发现name为null,自动过滤掉 or
                select user_id,user_name,email,age from user WHERE age > ?
            -->
            <if test="age > 0">
                or age > #{age}
            </if>
        </where>
    </select>


三、<foreach>标签

<foreach> 循环java中的数组,list集合的;主要用在sql的in语句中

语法:

    collection:表示接口中的方法参数的类型, 如果是数组使用array , 如果是list集合使用list
	item:自定义的,表示数组和集合成员的变量
	open:循环开始时的字符
	close:循环结束时的字符
    separator:集合成员之间的分隔符

<foreach collection="集合类型" item="自定义字段" open="开始字符" close="结束字符" separator="分隔字符">
    #{item的值}
</foreach>



collection


:表示接口中的方法参数的类型, 如果是数组使用array , 如果是list集合使用list



item


:自定义的,表示数组和集合成员的变量



open


:循环开始时的字符



close


:循环结束时的字符



separator


:集合成员之间的分隔符

1、遍历List<简单类型>

    <select id="selectForeachOne" resultType="com.mycompany.domain.User">
        select user_id,user_name,email,age
        from user
        <if test="list !=null and list.size > 0 ">
            where user_id in
            <foreach collection="list" item="myId" open="(" close=")" separator=",">
                #{myId}
            </foreach>
        </if>
    </select>

2、遍历List<对象类型>

    <select id="selectForeachTwo" resultType="com.mycompany.domain.User">
        select user_id,user_name,email,age
        from user
        <if test="list !=null and list.size > 0 ">
            where user_id in
            <foreach collection="list" item="user" open="(" close=")" separator=",">
                #{user.userId}
            </foreach>
        </if>
    </select>

我们也可将上述写法手动拼接,如:

    <select id="selectForeachTwo2" resultType="com.mycompany.domain.User">
        select user_id,user_name,email,age
        from user
        <if test="list !=null and list.size > 0 ">
            where user_id in (
                <foreach collection="list" item="user">
                    #{user.userId},
                </foreach>
            -1 )
        </if>
    </select>

四、SQL代码片段

<sql/>标签用于定义 SQL 片断,以便其它 SQL 标签复用;其它标签使用该 SQL 片断,使用 <include/>子标签

1、定义 <sql id="自定义名称唯一">  sql语句, 表名,字段等 </sql>
2、使用, <include refid="id的值" />

定义SQL片段如下:

    <sql id="selectUser">
        select user_id,user_name,email,age
        from user
    </sql>

    <sql id="selectUserOne">
        user_id,user_name,email,age
    </sql>

使用SQL片段如下:

    <select id="selectUsersWhere" resultType="com.mycompany.domain.User">
        <!-- select user_id,user_name,email,age
        from user -->

        <!-- select <include refid="selectUserOne" /> from user -->

        <include refid="selectUser" />

        <where>
            <if test="userName != null and userName != ''">
                user_name = #{userName}
            </if>
            <if test="age > 0">
                or age > #{age}
            </if>
        </where>
    </select>

五、mybatis判断list长度与数组长度

1、如果使用数组作为参数,那么使用length字段

 <if test="dataArr!=null and dataArr.length >0">

2、如果使用List作为参数,那么使用size()方法

 <if test="dataList!=null and dataList.size() >0">



版权声明:本文为MinggeQingchun原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。