动态sql

动态sql

sql的内容是变化的, 可以根据条件获取到不同的sql语句.

主要是where部分发生变化。

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

1. <if>是判断条件的

    // 动态Sql, 使用时候需要用Java对象作为参数
    // <if>测试
    List<Student> selectStudentIf(Student student);

    mapper文件

    <!--
        if
        参数:
        test : java对象的属性值作为判断条件
    -->
    <select id="selectStudentIf" resultType="org.example.domain.Student">
        select * from t_student where 1=1
        <if test="name != null and name != ''">
            name = #{name}
        </if>
        <if test="age >= 21">
            and age = #{age}
        </if>
    </select>

    <!--
        分析上面语法, 主sql为select * from t_student where
        当if中的test成立, 也就是说, 方法的参数java对象的name属性不为null且不为空字符串时
        将if语句块中的句子加入到主sql之后
        上述条件成立, sql语句变为select * from t_student where name = #{name}
        下面的age判断也一样, 如果成立就拼接, 不成立就不拼接

        所以上面的可能会出现sql语法错误, name不成立, age成立
        sql语句为 : select * from t_student where or age = #{age}
        这样是语法错误的

        为了避免这样的错误, 我们使用一个小技巧, 在主sql语句中加入一个一定成立的条件, 这个条件并不影响下面的条件
        如 : select * from t_student where id > 0
    -->

2. <where> 用来包含多个<if>的

    上面的if标签有局限性, 这个标签就可以很好的解决上面的问题

    // where使用
    List<Student> selectStudentWhere(Student student);

    mapper文件

    <select id="selectStudentWhere" resultType="org.example.domain.Student">
        select * from t_student
        <where>
            <if test="name != null and name != ''">
                name = #{name}
            </if>

            <if test="age >= 21">
                and age = #{age}
            </if>
        </where>
    </select>
    <!--
    where的作用就是处理上面多个if只有一个生效的问题,
    select语句中不用写if了, 转而用<where>标签代替
    当多个if只有一个生效时, where标签会自动将SQL语句中别的影响语句语法的信息删除
    -->

3. <foreach>是用来循环java中的数组, list集合

    主要用在sql的in语句中

    select * from student where id in (1, 2, 3)

    dao中方法为

    List<Student> selectFor(List<Integer> idList)

    这个idList中存放的就是上面的1, 2, 3

    一般有两种情况

        1. 参数为List<基本类型>

        // foreach用法1, 参数为List<基本类型>
        List<Student> selectForeachOne(List<Integer> idList);

        mapper文件
 

        <!--
            foreach用法1, 接口方法参数为List<基本类型>
            List<Student> selectForeachOne(List<Integer> idList);
        -->
        <!--
            参数介绍
            collection:表示接口中的方法参数的类型, 如果是数组使用array, 如果是List集合使用list
            item:自定义的, 表示数组和集合成员的变量, 好比for(Integer i : List)中的i
            open:循环开始时最前面添加的字符
            close:循环结束时最后面添加的字符
            separator:集合成员之间的分隔符
        -->
        <select id="selectForeachOne" resultType="org.example.domain.Student">
            select * from t_student where id in
            <foreach collection="list" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </select>
        <!--
            最后循环的结果(为传入的list为(1, 2, 3))
            select * from t_student where id in (1, 2, 3)
            这里是字符串的拼接, 所以完全可以这样写
            select * from t_student where id in (
                <foreach collection="list" item="id" separator=",">
                    #{id}
                </foreach>
            )
        -->

       2. 参数为List<自定义类型>

        // foreach用法2, 参数为List<自定义类型>
        List<Student> selectForeachTwo(List<Student> students);

 

        <!--
            传入参数为list<Student>
            #{item的值.属性}
        -->
        <select id="selectForeachTwo" resultType="org.example.domain.Student">
            select * from t_student where id in
            <foreach collection="list" item="stu" open="(" close=")" separator=",">
                #{stu.id}
            </foreach>
        </select>
        <!--
            这样将List中的每个Student对象的id循环拼接
        -->


 4. sql代码片段, 就是复用一些语法

    <!--
        sql代码片段, 可以复用
        先定义 : <sql id="唯一标识符" >可以复用的sql语句</sql>
        再使用 : <include refid="id的值" />
    -->
    <!--定义-->
    <sql id="sqlStu" >
        select * from t_student
    </sql>
    <!--使用-->
    <select id="selectForSql" resultType="org.example.domain.Student">
        <include refid="sqlStu"/>
    </select>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值