6 动态sql

本文介绍了Mybatis框架中的动态SQL技术,如何使用if、trim、choose和foreach标签处理多条件查询中的空值问题,以及如何处理集合参数的插入和删除操作,包括使用不同的SQL片段引用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis框架的动态sql技术是一种根据特定条件动态拼装sql语句的功能,它存在的意义是为了解决拼接sql语句字符串的痛点问题

比如在sql查询语句中,你的参数一般是来自服务器,服务器的数据有可能来自session之类的,例如多条件查询,你有个条件为空,那传了个空值给sql语句的参数会导致sql语句查询报错,但是你又不能把这个条件从where中去除,所以可以采用动态sql

  • if标签
    • 在sql语句标签内可以使用if标签
    • List<Emp> getEmpByCondition(Emp emp);
    • <select id="getEmpByCondition" resultType="Emp">
      • select * from t_emp where
      • <if test="empName != null and empName != ''">
        • emp_name = #{empName}
      • </if>
      • <if test="age != null and age != ''">
        • and age = #{age}
      • </if>
      • <if test="gender != null and gender != ''">
        • and gender = #{gender}
      • </if>
    • </select>
    • 在select标签中使用if标签,其中的test属性中填写条件语句,标签内填写拼接的sql语句,test可以直接使用传进来的参数不用加#{},除了这个以外其它的和之间的参数使用方式是一样的
  • where标签
    • 上面的if标签中我给的示例,假如我第一个条件不成立,第二个条件成立,那么where后面会直接拼接and,就会报错
      • 解决办法1,在where语句后面加一个1=1,然后所有的拼接语句加上and
      • 解决办法2,where标签
        • 功能1 在条件if标签中只要有成立条件在sql语句中自动生成where语句
        • 功能2 可以自动去掉where后面因为sql语句拼接前面多余的and,就不会出现where and 这种错误语句,但是可能会出现where xxx and xxx and 以and结尾这种错误语句
        • 功能3 当条件语句中没有成立条件将不会生成where
          • <select id="getEmpByCondition" resultType="Emp">
            • select * from t_emp
            • <where>
              • <if test="empName != null and empName != ''">
                • emp_name = #{empName}
              • </if>
              • <if test="age != null and age != ''">
                • and age = #{age}
              • </if>
              • <if test="gender != null and gender != ''">
                • and gender = #{gender}
              • </if>
            • </where>
          • </select>
  • trim标签
    • 因为where标签虽然可以自动去掉拼接前面的and,但是不能去掉后面的and
    • trim标签有四个属性
      • 下面的sql语句指定都是添加的总拼接语句,就是下面例子后面t_emp后面拼接的所有部分
      • prefix:给sql语句拼接的前缀
      • prefixOverriders:去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
      • suffix:给sql语句拼接的后缀
      • suffixOverriders:去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
    • <select id="getEmpByCondition" resultType="Emp">
      • select * from t_emp
      • <trim prefix="where" suffixOverrides="and">
        • <if test="empName != null and empName != ''">
          • emp_name = #{empName} and
        • </if>
        • <if test="age != null and age != ''">
          • age = #{age} and
        • </if>
        • <if test="gender != null and gender != ''">
          • and gender = #{gender} and
        • </if>
      • </trim>
    • </select>
    • 由于trim标签,会自动在拼接语句前面拼接where(有条件成立的前提),还会去掉sql语句最后的and
  • choose,when,otherwise
    • choose:相当于if
    • when:相当于else if
    • otherwise:相当于else
    • 这一组标签和if标签的区别就是他是众多条件最后只会成立一个,而if可以有多个条件成立
      • <select id="getEmpByCondition" resultType="Emp">
        • select * from t_emp
        • <where>
          • <choose>
            • <when test="empName != '' and empName != null">
              • emp_name = #{emName}
            • </when>
            • <when test="age != '' and age != null">
              • and age = #{age}
            • </when>
            • <when test="gender != '' and gender != null">
              • and gender = #{gender}
            • </when>
          • </choose>
        • </where>
      • </select>
    • otherwise可用可不用
  • foreach标签(用的多)
    • 批量添加
    • void insertEmpList(List<Emp> list); 使用集合添加
      • 关于参数是list集合,那么在mybatis中怎么访问,之前似乎没遇到过,有两种吧,一种是mybatis默认会吧集合参数放到它的map集合中,以"list" 为键,以传进来的参数位置 #{list},另一种就是用@param的方法 直接 #{(param注解中的值)}
    • 映射文件写法
      • <insert id="insertEmpList">
        • <foreach collection="list" item="emp" separator=",">
          • (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        • </foreach>
      • </insert>
      • 解释一下
        • 上面的collection属性值为传过来的参数,具体使用和之前if标签中的text使用参数的方式一样,不需要加#{},只要有list这个键名和对应的值就行
        • item属性表示从集合了取出来对象,然后给对象赋予键名为emp,值为list中取出来的对象
        • separator表示分隔符,用来分隔每条循环语句的,不会在总拼接语句的开头和结尾添加,只分隔中间的语句,而且会在分各符前后加空格
        • 然后注意使用对象的属性的方式#{emp.name}
    • 批量删除
      • 之前有一种where emp_id in (xxx,xxx) 这种删除方法,用的是${}来拼接到括号里面删除
      • 第二种的语句跟上一种差不多,只是参数使用有区别
        • 通过传入id数组
        • void deleteMoreEmp(@Param("emps") Integer[] integers);
        • 使用foreach标签来删除
          • <delete id="deleteMoreEmp">
            • delete from t_emp where emp_id in (
              • <foreach collection="emps" item="empId" separator=",">
                • #{empId}
              • </foreach>
            • )
          • </delete>
          • 这样通过循环将参数全放入in ( ) 的括号里的方式
        • 另一种就是
          • <delete id="deleteMoreEmp">
            • delete from t_emp where emp_id in
            • <foreach collection="emps" item="empId" separator="," open="(" close=")">
              • #{empId}
            • </foreach>
          • </delete>
        • 这里open和close分别表示总拼接语句的开始和结束符,这里会为总拼接语句开始加(和结束加)最后就会变成(?,?,?)的形式
        • 还有一种
          • <delete id="deleteMoreEmp">
            • delete from t_emp where
            • <foreach collection="emps" item="empId" separator="or">
              • emp_id = #{empId}
            • </foreach>
          • </delete>
        • 利用了分隔符会前后补空格的机制,可以这样写
  • sql标签
    • 主要是用来记录一个sql片段,在需要用的地方使用include标签来应用
    • <sql id="empfield">
      • emp_id,emp_name,age,gender
    • </sql>
    • 将这个sql片段记录
    • <select id="xxxx">
      • select <include refid="empfield"></include> from t_emp
    • </select>
    • 在使用的地方用include标签引用,refid就是sql标签的id
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值