MyBatis动态sql

一、动态Sql

通过MyBatis提供的各种标签方法实现动态拼接Sql。

这些标签类似于JSTL标签,可以写控制语句动态的拼接Sql

二、if标签、where标签

使用了 <where>标签自动处理 AND 前缀,<where>​只处理第一个 AND​(如果存在),后续的 AND不会受影响。

如:WHERE name LIKE '%zz%' AND age = 23 AND gender = '女'

<where>会去掉第一个 AND(AND name LIKE...→ name LIKE...),后续的 AND保留。

通过 <if>标签实现条件判断:

当 name不为空时,添加模糊查询条件

当 age不为空时,添加精确匹配条件

当 gender不为空时,添加精确匹配条件

例:

java 复制代码
<select id="selectByCondition" parameterType="Student" resultMap="studentMap">

    SELECT <include refid="studentColumns"/>

    FROM student

    <where>

        <if test="name!=null and name!=''">

            AND name LIKE concat('%',#{name},'%')

        </if>

        <if test="age!=null">

            AND age=#{age}

        </if>

        <if test="gender!=null and name!=''">

            AND gender=#{gender}

        </if>

    </where>

</select>

 

测试类

@Test

public void testselectByCondition() throws IOException {

    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    Student stu = new Student();

    stu.setName("王");

    stu.setGender("女");

    List<Student> list = sqlSession.selectList("student.selectByCondition", stu);

    for (Student student : list) {

        System.out.println(student);

    }

}

三、set标签

在更新数据有些时候希望User里面只有属性值有数据的才去做更新操作,属性没有数据的时候不做任何操作还是原来的值。

update user set name=?,age=?,gender=? where id=?;

在根据条件拼接sql时候有一个问题,如果想统一处理,最后一个","处理起来麻烦。

<set>标签用于动态生成 SET子句,并​自动去除末尾多余的逗号(,)

java 复制代码
<update id="updateCondition" parameterType="Student">

    UPDATE student

        <set>

            <if test="name!=null and name!=''">

                name=#{name},

            </if>

            <if test="age!=null">

                age=#{age},

            </if>

            <if test="gender!=null and gender!=''">

                gender=#{gender},

            </if>

        </set>

    WHERE id=#{id}

</update>

 

测试类

@Test

public void testUpdateCondition() {

    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    Student student = new Student();

    student.setId(1);

    student.setName("小李1");

    student.setAge(25);

    //student.setGender("女");

    int count = sqlSession.update("student.updateCondition", student);

    System.out.println(count);

    sqlSession.commit();

}

四、foreach标签

处理数组或者集合,MyBatis使用foreach标签解析。

做一个批量删除的操作,参数可以是集合或是数组的形式传递过来:int[] idArray = {1,2,3,4};、List idList;

java 复制代码
<delete id="deleteAllByArray">

    DELETE FROM student

    WHERE id IN

        <foreach collection="array" open="(" item="id" close=")" separator=",">

            #{id}

        </foreach>

</delete>





测试类



@Test

public void testDeleteAllByArray() {

    int[] array = {8,9,11};

    SqlSession sqlSession = MyBatisUtil.getSqlSession();;

    int count = sqlSession.delete("student.deleteAllByArray", array);

    System.out.println("count: " + count);

    sqlSession.commit();

    sqlSession.close();

}

collection="array"​​:表示参数是一个​​数组​​(如 int[]或 String[])。

​​open="("和 close=")"​​:生成 IN语句的括号 ( )。

​​separator=","​​:用逗号分隔多个 ID。

​​item="id"​​:遍历时的临时变量名,在 #{id}中使用。

​collection="list"​:表示参数是一个 ​List​(如 List<Integer>或 List<String>)。

​​open="("和 close=")"​​:生成 IN语句的括号 ( )。

​​separator=","​​:用逗号分隔多个 ID。

​​item="id"​​:遍历时的临时变量名,在 #{id}中使用。

java 复制代码
<delete id="deleteAllByList">

    DELETE FROM student

    WHERE id IN

           <foreach collection="list" open="(" item="id" close=")" separator=",">

               #{id}

           </foreach>

</delete>



测试类

@Test

public void testDeleteAllByList() {

    List<Integer> list = new ArrayList<>();

    list.add(4);

    list.add(6);

    SqlSession sqlSession = MyBatisUtil.getSqlSession();;

    int count = sqlSession.delete("student.deleteAllByList", list);

    System.out.println("count: " + count);

    sqlSession.commit();

    sqlSession.close();

}

五、choose、when、otherwise

if----else if----else if ----else

​<choose>、<when>、<otherwise>​ 标签实现​多条件分支选择​,只会执行第一个满足条件的 <when>分支​​,后续条件即使成立也会被忽略。

例如:

如果用户填写了名字,这个搜索就按照名字来搜索,你即使填写了别的条件也不去拼接,

如果没有填写名字,填写了年龄,就按照年龄来搜索,

如果名字和年龄都没有填写,但是填写了性别就按照性别来查找

name、age、gender搜索时候只能按照其中一个来搜索,但是优先级name>age>gender

执行逻辑

1.按顺序检查 <when>条件:
如果 name非空,生成 name LIKE '%值%',忽略后续条件。
如果 name为空但 age非空,生成 age=值,忽略后续条件。
如果 name和 age都为空但 gender非空,生成 gender=值。
2.所有条件都不满足:<otherwise>为空,最终 SQL 可能变成 WHERE后无内容(需注意语法错误)。

java 复制代码
<select id="selectByCondition2" parameterType="Student" resultMap="studentMap">

    SELECT <include refid="studentColumns"/>

        FROM student

    WHERE

        <choose>

            <when test="name!=null and name!='' ">

                name LIKE concat('%',#{name},'%')

            </when>

            <when test="age!=null">

                age=#{age}

            </when>

            <when test="gender!=null and gender!=''">

                gender=#{gender}

            </when>

            <otherwise></otherwise>

        </choose>

</select>

 

@Test

public void testSelectByCondition1() {

    Student student = new Student();

    //student.setName("王");

    student.setAge(23);

    student.setGender("女");

    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    List<Student> list = sqlSession.selectList("student.selectByCondition2", student);

    for (Student s : list) {

        System.out.println(s);

    }

}

六、trim

MyBatis 中的<trim>标签是一个特殊的动态 SQL 元素,它用于在动态生成 SQL 语句时自动添加或删除前后缀,以及在多个元素之间添加分隔符。这在构建包含多个可选部分的 SQL 语句时非常有用,例如在 INSERT、UPDATE 或 WHERE 子句中。

<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="" ></trim>

<trim>标签提供了以下几个属性:

  • prefix:在生成的 SQL 中添加的前缀。
  • prefixOverrides:用于删除前缀中的特定字符。
  • suffix:在生成的 SQL 中添加的后缀。
  • suffixOverrides:用于删除后缀中的特定字符。与 prefixOverrides 类似,但用于删除尾随的字符。
相关推荐
那我掉的头发算什么3 小时前
【数据结构】双向链表
java·开发语言·数据结构·链表·intellij-idea·idea
半桔3 小时前
【STL源码剖析】从源码看 list:从迭代器到算法
java·数据结构·c++·算法·stl·list
拾光Ծ3 小时前
【C++】STL之list模拟实现:关于链表容器的双向迭代器你知道多少?
开发语言·数据结构·c++·list·visual studio
666HZ6663 小时前
Java Stream流
java·开发语言
数模加油站3 小时前
最新R(4.4.1)及R-studio保姆级安装配置详细教程及常见问题解答
开发语言·windows·数学建模·r语言
编程指南针3 小时前
2026新选题-基于Python的老年病医疗数据分析系统的设计与实现(数据采集+可视化分析)
开发语言·python·病历分析·医疗病历分析
学编程的小鬼3 小时前
全局异常处理器
java·spring boot
reasonsummer4 小时前
【办公类-116-01】20250929家长会PPT(Python快速批量制作16:9PPT相册,带文件名,照片横版和竖版)
java·数据库·python·powerpoint
暴力求解4 小时前
数据结构---栈和队列详解(上)
开发语言·数据结构·c++