Mybatis动态sql

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>
posted @ 2024-08-14 11:38  GrowthRoad  阅读(28)  评论(0编辑  收藏  举报