MySQL动态sql

mybatis动态sql

mybatis使用xml映射文件创建动态sql语句

一、动态sql语法

  • :用于判断条件是否成立,如果条件为true,则拼接SQL
  • :只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
  • :动态的在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中)
  • :遍历deleteByIds方法中传递的参数ids集合
  • :定义可重用的SQL片段
  • :通过属性refid,指定包含的SQL片段

二、使用

一、if & where,条件查询
  • <if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。
<if test="条件表达式">
   要拼接的sql语句
</if>
  • <where>只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR

使用示例:

<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        <where>
             <!-- if做为where标签的子元素 -->
             <if test="name != null">
                 and name like concat('%',#{name},'%')
             </if>
             <if test="gender != null">
                 and gender = #{gender}
             </if>
             <if test="begin != null and end != null">
                 and entrydate between #{begin} and #{end}
             </if>
        </where>
        order by update_time desc
</select>

测试方法:

@Test
public void testList(){
    //只有性别
    List<Emp> list = empMapper.list(null, (short)1, null, null);
    for(Emp emp : list){
        System.out.println(emp);
    }
}

执行的SQL语句:

在这里插入图片描述

解释为什么需要使用where,如果我们不使用<where>,那么就会出现如下可能,if条件有时全为false时,就会多出一个where出来,像以上示例,如果全为false,那么这条sql语句就为select * from emp where order by update_time desc,出现语法错误,使用<where>就能够去除多余的where,保证sql的正确

二、set,更新语句
  • <set>:动态的在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">

    <!--更新操作-->
    <update id="update">
        update emp
        <!-- 使用set标签,代替update语句中的set关键字 -->
        <set>
            <if test="username != null">
                username=#{username},
            </if>
            <if test="name != null">
                name=#{name},
            </if>
            <if test="gender != null">
                gender=#{gender},
            </if>
            <if test="image != null">
                image=#{image},
            </if>
            <if test="job != null">
                job=#{job},
            </if>
            <if test="entrydate != null">
                entrydate=#{entrydate},
            </if>
            <if test="deptId != null">
                dept_id=#{deptId},
            </if>
            <if test="updateTime != null">
                update_time=#{updateTime}
            </if>
        </set>
        where id=#{id}
    </update>
</mapper>

测试方法

@Test
public void testUpdate2(){
        //要修改的员工信息
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUsername("Tom222");
      
        //调用方法,修改员工数据
        empMapper.update(emp);
}

测试结果:

在这里插入图片描述

解释,假设不使用<set>,如果这里只有username条件满足,那么sql语句就为update emp set username = ?,where id = ?,多出一个逗号,,而<set>就可以去除这个逗号

三、foreach,批量操作

案例:员工删除功能(既支持删除单条记录,又支持批量删除)

在这里插入图片描述

SQL语句:

delete from emp where id in (1,2,3);

Mapper接口:

@Mapper
public interface EmpMapper {
    //批量删除
    public void deleteByIds(List<Integer> ids);
}

XML映射文件:

  • 使用<foreach>遍历deleteByIds方法中传递的参数ids集合
<foreach collection="集合名称" item="集合遍历出来的元素项" separator="每一次遍历使用的分隔符" 
         open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
</foreach>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
    <!--删除操作-->
    <delete id="deleteByIds">
        delete from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper> 
四、sql & include

这两个一般都是配合使用的

问题分析:

  • 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码

在这里插入图片描述

在这里插入图片描述

我们可以对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后再通过<include>标签进行引用。

  • <sql>:定义可重用的SQL片段

  • <include>:通过属性refid,指定包含的SQL片段

在这里插入图片描述

SQL片段: 抽取重复的代码

<sql id="commonSelect">
 	select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>

然后通过<include> 标签在原来抽取的地方进行引用。操作如下:

<select id="list" resultType="com.itheima.pojo.Emp">
    <include refid="commonSelect"/>
    <where>
        <if test="name != null">
            name like concat('%',#{name},'%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>

完整代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.itheima.mapper.EmpMapper">

    <!-- 公共SQL片段 -->
    <sql id="commonSelect">
        select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
    </sql>

    <!-- 使用公共SQL片段和条件过滤查询员工列表 -->
    <select id="list" resultType="com.itheima.pojo.Emp">
        <include refid="commonSelect"/>
        <where>
            <if test="name != null">
                name like concat('%', #{name}, '%')
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="begin != null and end != null">
                and entrydate between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>

</mapper>

           and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>

相关推荐

  1. 17. Mysql 动态SQL

    2024-06-16 17:54:02       58 阅读
  2. <span style='color:red;'>动态</span><span style='color:red;'>sql</span>

    动态sql

    2024-06-16 17:54:02      32 阅读
  3. <span style='color:red;'>动态</span><span style='color:red;'>sql</span>

    动态sql

    2024-06-16 17:54:02      34 阅读
  4. MyBatis动态SQL(Dynamic SQL)

    2024-06-16 17:54:02       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-16 17:54:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-16 17:54:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-16 17:54:02       82 阅读
  4. Python语言-面向对象

    2024-06-16 17:54:02       91 阅读

热门阅读

  1. 学习分享-FutureTask

    2024-06-16 17:54:02       31 阅读
  2. 基于深度学习的物体材质预测

    2024-06-16 17:54:02       31 阅读
  3. iOS cell的复用以及自定义cell

    2024-06-16 17:54:02       39 阅读
  4. lwip中server和client的socket、地址和端口号

    2024-06-16 17:54:02       35 阅读
  5. DOM的概念?获取html元素的方法有哪些?

    2024-06-16 17:54:02       25 阅读
  6. 深入浅出Python爬虫:掌握数据抓取的艺术

    2024-06-16 17:54:02       24 阅读
  7. lower_bound 和 upper_bound

    2024-06-16 17:54:02       34 阅读
  8. UOS常用命令

    2024-06-16 17:54:02       24 阅读
  9. Spring Boot 增删改查(mybatis-plus)

    2024-06-16 17:54:02       32 阅读
  10. Vue中双向数据绑定是如何实现的

    2024-06-16 17:54:02       28 阅读
  11. dev c++ “permission denied“解决方法

    2024-06-16 17:54:02       34 阅读
  12. 每天一个项目管理概念之敏捷项目管理

    2024-06-16 17:54:02       31 阅读
  13. MongoDB入门与实践

    2024-06-16 17:54:02       28 阅读
  14. 了解protoStuff

    2024-06-16 17:54:02       33 阅读