SQL动态语句 where和if标签的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL动态语句 where和if标签的使用相关的知识,希望对你有一定的参考价值。

参考技术A 1.resultType返回的是封装的实体类。返回的字段必须跟实体类的字段相同,不然有的数据会报空。

2.实体类封装

Java--MyBatis动态SQL;<if>,<where>,<foreach>标签

动态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>

以上是关于SQL动态语句 where和if标签的使用的主要内容,如果未能解决你的问题,请参考以下文章

在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句:

MyBatis—07—DQL: 动态SQL查询;

动态SQL (if , choose (when, otherwise) , trim (where, set) , set, foreach)

MyBaits入门完结篇

mybatis-动态sql

动态SQL之标签