首页 > 数据库 >Mybatis动态sql

Mybatis动态sql

时间:2024-08-14 11:38:38浏览次数:11  
标签:salary name 标签 emp sql Mybatis 动态 where

Mybatis动态sql

在创建sql语句时,有时会遇到 传入的参数为空的问题,也就是某些条件有时候不取值。这时就可以用动态sql来创建sql语句,不用自己拼接sql语句。

1.if 和 where 标签

在sql语句条件外面包一层 if 标签,if标签的 属性test 可以进行判断,当判断为true后才会把标签内部的条件拼接到sql语句中,为false就不拼接。

<mapper namespace="com.ztone.mapper.EmployeeMapper">
    <select id="queryEmployee" resultType="employee">
        select * from t_emp where
            <if test="name != null">
                emp_name = #{name}
            </if>
            <if test="salary != null">
               and emp_salary = #{salary}
            </if>
    </select>
</mapper>

这样就会出现几个问题

  • 当第一个条件不满足,而第二个条件满足,那么sql语句就会变成这样

    select * from t_emp where and emp_salary = #{salary}

  • 当第一个条件和第二个条件都不满足,sql变成这样

    select * from t_emp where

这两种情况形成的sql语句显然都是错误的,多了 where 或 and,这时候可以使用 where 标签

<mapper namespace="com.ztone.mapper.EmployeeMapper">
    <select id="queryEmployee" resultType="employee">
        select * from t_emp 
            <where>
                <if test="name != null">
                    emp_name = #{name}
                </if>
                <if test="salary != null">
                    and emp_salary = #{salary}
                </if>
            </where>
    </select>
</mapper>

where标签可以

  • 自动添加where关键字,当他发现where 标签中有if判断满足,就会自动添加where,否则不添加

  • 自动去掉多余的 and 或 or 关键字

 

2.set标签

set标签和where类似,

在更新数据时会自动添加set关键字以及去掉多余的 “,”

<update id="updateEmployee">
    update t_emp
    <set>
        <if test="empName != null">
            emp_name = #{empName},
        </if>
        <if test="empSalary != null">
            emp_salary = #{empSalary}
        </if>
    </set>
    where emp_id = {empId}
</update>

如果不添加set标签,那么当第二个条件不满足,第一个条件满足时sql语句就会多一个 逗号

 

3.trim 标签

trim 标签可以替代 where 和 set 标签,动态添加关键字,去掉多余的关键字

trim的属性:

  • prefix:指定要动态添加的前缀

  • suffix:指定要动态添加的后缀

  • prefixOverrides:指定要动态去掉的前缀,使用 | 分隔多个值

  • suffixOverrides:指定要动态去掉的后缀,使用 | 分隔多个值

<select id="queryEmployee" resultType="employee">
    select * from t_emp 
        <trim prefix="where" prefixOverrides="and">
            <if test="name != null">
                emp_name = #{name}
            </if>
            <if test="salary != null">
                and emp_salary = #{salary}
            </if>
        </trim>
</select>

 

4.choose/when/otherwise 标签

在多个分支中,只执行一个分支,和Java中的 switch case类似

如果都不满足,最后走 otherwise 标签

<select id="queryEmployee1" resultType="employee">
    select * from t_emp
    <where>
        <choose>
            <when test="name != null">
                emp_name = #{name}
            </when>
            <when test="salary != null">
                and emp_salary = #{salary}
            </when>
            <otherwise>1=1</otherwise>
        </choose>
    </where>
</select>

 

5.foreach标签

该标签是在sql语句中的遍历操作

foreach 的属性:

  • collection:要遍历的集合,也就是传进来的参数,这里最好用 @Param起名字,也可以用 arg0或list

  • open:遍历之前要追加的字符串

  • close:遍历之后要追加的字符串

  • separator:每次遍历的分隔符,最后一次遍历不会追加该分隔符

  • item:获取每个遍历项

案例:

查询多个员工。sql:select * from t_emp where emp_id in (1,2,3); 这里要遍历的部分是 括号内的id

<!--    List<Employee> queryBatch(@Param("ids") List<Integer> allId);-->
<select id="queryBatch" resultType="employee">
    select * from t_emp where emp_id in
        <foreach collection="ids" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
</select>

 

删除多个员工。sql:delete from t_emp where emp_id in (1,2,3) ;

<!--    int deleteBatch(@Param("ids") List<Integer> allId);-->
<delete id="deleteBatch">
    delete from t_emp where emp_id in
        <foreach collection="ids" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
</delete>

 

插入多个员工。sql:insert into t_emp(emp_name,emp_salary) values ("xx",100),("ss",200); 这里遍历的是("xx",100)

<!--    int insertBatch(@Param("list") List<Employee> employees);-->
<insert id="insertBatch">
    insert into t_emp(emp_name,emp_salary) values
        <foreach collection="list" item="employee">
            (#{employee.empName},#{employee.empSalary})
        </foreach>
</insert>

 

更新多个员工。 sql:update t_emp set emp_name=#{empName},emp_salary=#{empSaraly} where emp_id={empId} 需要遍历的是整个sql语句

<!--    int updateBatch(@Param("list") List<Employee> employees);-->
<update id="updateBatch">
    <foreach collection="list" item="employee">
        update t_emp set  emp_name=#{employee.empName},emp_salary=#{employee.empSaraly}
            where emp_id={employee.empId}
    </foreach>
</update>

如果要执行多个sql语句,需要在 数据库的url 中追加 allowMultiQueries=true 这个参数 允许多语句执行

 

6.sql片段

sql标签用来提取相同的sql语句,避免重复编写

sql标签的属性 id 代表该标签的名字,在用到该sql片段的地方,用 include标签 引入,include标签的属性refid的值就是sql标签的id值

<sql id="selectSql">
    select * from t_emp
</sql>
​
<select id="queryEmployee" resultType="employee">
    <include refid="selectSql"/>
        <trim prefix="where" prefixOverrides="and">
            <if test="name != null">
                emp_name = #{name}
            </if>
            <if test="salary != null">
                and emp_salary = #{salary}
            </if>
        </trim>
</select>

标签:salary,name,标签,emp,sql,Mybatis,动态,where
From: https://www.cnblogs.com/wztblogs/p/18358564

相关文章

  • 【SQL】项目员工 I
    目录题目分析代码题目项目表 Project: +-------------+---------+|ColumnName|Type|+-------------+---------+|project_id|int||employee_id|int|+-------------+---------+主键为(project_id,employee_id)。employee_id是员工表......
  • 【SQL】确认率
    目录题目分析代码题目表: Signups+----------------+----------+|ColumnName|Type|+----------------+----------+|user_id|int||time_stamp|datetime|+----------------+----------+User_id是该表的主键。每一行都包含ID......
  • 【SQL】平均售价
    目录题目分析代码题目表:Prices+---------------+---------+|ColumnName|Type|+---------------+---------+|product_id|int||start_date|date||end_date|date||price|int|+---------------+-------......
  • Sy.ExpressionBuilder 动态查询新体验
    省流模式,看下对比//常规查询varquery=users.WhereIf(m=>m.UserName.Contains(input.UserName),!string.IsNullOrEmpty(input.UserName)).WhereIf(m=>input.RoleIds.Contains(m.RoleId),input.RoleIds?.A......
  • docker 运行 postgresql
    docker运行postgresql服务端及客户端 注意:是postgres不是postgre!!! 1.orb里设置{"registry-mirrors":["https://改成你的.mirror.aliyuncs.com","https://docker.888666222.xyz"],"ipv6":true} 2.访问https://docker.registry.cyo......
  • mysql 创建定时任务清理指定表
    一、创建定时任务1、确保MySQL的事件调度器已经开启。可以通过以下SQL命令检查是否开启:SHOWVARIABLESLIKE'event_scheduler';2、如果返回的值为OFF,则可以通过以下命令开启事件调度器:SETGLOBALevent_scheduler=ON;3、以下是一个删除your_table表中7天前数据的示例:......
  • GreatSQL 并行Load Data加快数据导入
    GreatSQL并行LoadData加快数据导入数据库信息数据库版本:GreatSQL8.0.32-25Clickhouse表需要导入到GreatSQL中,表数据量庞大所以选用导出CSV的方式。测试数据复现操作loaddataMySQLloaddata语句能快速将一个文本文件的内容导入到对应的数据库表中(一般文本的一行对应......
  • 动态规划-不同路径问题
    本篇是动态规划算法题目介绍的第二篇,如果对其他题目感兴趣的话,可以前往动态规划_Yuan_Source的博客-CSDN博客不同路径Ⅰ一个机器人位于一个 mxn 网格的左上角。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。问总共有多少条不同的路径?解题思路......
  • 动态规划:最长回文子串
    目录题目思路解题过程复杂度code 题目        给你一个字符串 s,找到 s 中最长的 回文子串示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"提示:1<=s.length<=1000s 仅由数字和英文字母组成......
  • 【漏洞复现】普华-PowerPMS APPGetUser SQL注入漏洞
             声明:本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动,将与本文档的作者或发布者无关。一、漏洞描述PowerPMS是一款综合性的企业管理系统,它集成了财务管理、销售管理、采购管理、仓储管理以及项目管理等多个功......