5.Mybatis动态SQL

动态SQL

  1. 根据不同的条件需要执行不同的 SQL 命令,称为动态 SQL
  2. MyBatis 中动态 SQL 在 mapper.xml 中添加逻辑判断等

mapper.xml文件对应的接口文件:

package com.bjsxt.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.bjsxt.pojo.Log;

public interface LogMapper {
	
    List<Log> selByAccinAccout(@Param("accout") String accout, @Param("accin") String accin);
	
	int upd(Log log);
	
	List<Log> selByLog(Log log);
	
	List<Log> selIn(List<Integer> list);
	
	int ins(List<Integer> list);
}

if 标签

<select id="selByAccinAccout" resultType="log"> <!-- 同样的,resultType为一行的返回类型 -->
    select * from log where 1=1  <!-- where后边的1=1是防止生成的sql语句语法错误(and引起) -->
<!-- OGNL 表达式,直接写 key 或对象的属性.不需要添加任何特殊符号 --> 
    <if test="accin!=null and accin!=''">  
        <!-- if标签中的test属性中条件满足,生成的sql语句中才会有下边的and ... -->
        and accin=#{accin} 
    </if> 
    <if test="accout!=null and accout!=''"> 
        and accout=#{accout} 
    </if> 
</select>

where标签

  • 当编写 where 标签时,如果内容中开头是 and,则会去掉第一个and(不用再写1=1)
  • 如果中有内容会生成 where 关键字,如果没有内容不生成 where 关键字
  • 使用示例
    • 比直接使用少写 where 1=1
<select id="selByAccinAccout" resultType="log"> 
    select * from log 
    <where>  <!-- 有内容会自动添加where -->
        <if test="accin!=null and accin!=''"> 
            and accin=#{accin}  <!-- 并且如果语句开头是and,会自动去掉and -->
        </if> 
        <if test="accout!=null and accout!=''"> 
            and accout=#{accout} 
        </if> 
    </where> 
</select>

choose,when,otherwise标签

  • 只有有一个成立,其他都不执行
  • 代码示例
    • 如果 accin 和 accout 都不是 null 或不是””空串,生成的sql 中只有 where accin=?
<select id="selByAccinAccout" resultType="log"> 
    select * from log 
    <where>
        <choose> 
            <when test="accin!=null and accin!=''">
                and accin=#{accin} 
            </when> 
            <when test="accout!=null and accout!=''"> 
                and accout=#{accout} 
            </when> 
        </choose> 
    </where> 
</select>

set 标签

用在修改(update) SQL 中 set 从句

  • 作用:去掉最后一个逗号
  • 作用:如果里面有内容则会生成 set 关键字,没有就不生成
  • 示例
    • id=#{id} 目的防止中没有内容,mybatis 不生成 set 关键字
    • 如果修改中没有 set 从句,那么会有 SQL 语法错误
<update id="upd" parameterType="log" > 
    update log 
    <set> 
        id=#{id}, 
        <if test="accIn!=null and accIn!=''"> 
            accin=#{accIn}, 
        </if> 
        <if test="accOut!=null and accOut!=''">
            accout=#{accOut}, 
        </if> 
    </set> 
    where id=#{id} 
</update>

trim 标签

  • prefix 在前面添加内容

  • prefixOverrides 去掉前面内容

  • suffix 在后面添加内容

  • suffixOverrides 去掉后面内容

  • 注意:执行顺序为:先去掉内容,后添加内容(如where中,如果先添加where,那么第一个就不是and了,而原本要去掉的and也就不会自动去掉)

  • 代码示例 (trim模拟set功能)

<update id="upd" parameterType="log"> 
    update log 
    <trim prefix="set" suffixOverrides=",">  
        <!-- 注意:这里在前边加上set之后在set后边会多一个空格,精确控制值可以使用下边的bind标签 -->
        a=a, 
    </trim> 
    where id=100 
</update>

bind 标签

  • 作用:给参数重新赋值
  • 场景:
    • 模糊查询
    • 在原内容前边或者后边添加内容
<select id="selByLog" parameterType="log" resultType="log"> 
    <bind name="accin" value="'%'+accin+'%'"/>  <!-- 传进来的参数为Log对象,accin为对象属性 -->
    <!-- 而value把accin属性的值替换 -->
    #{...} 
</select>

foreach 标签

  • 循环参数内容,还具备在内容的前后添加内容,并且还具备添加分隔符功能

  • 适用场景:in 查询中,批量新增中(mybatis 中 foreach 效率比较低)

  • 如果希望批量新增,SQL 命令

insert into log 
values(default,1,2,3),(default,2,3,4),(default,3,4,5);

​ 那么openSession()必须指定:

​ 底层 JDBC 的PreparedStatement.addBatch();
factory.openSession(ExecutorType.BATCH);

  • foreach标签的属性:

    • collection=”” 表示要遍历的集合(一般为传进来的参数)
    • item 迭代的变量(类比jstl中foreach的var), #{迭代变量名}获取内容
    • open 循环后左侧添加的内容 (注意,是整个循环结果之前)
    • close 循环后右侧添加的内容 (注意,是整个循环结果之后)
    • separator 每次循环时,元素之间的分隔符 (注意,是单次循环结果之后)
  • 示例

<select id="selIn" parameterType="list" resultType="log"> 
    select * from log where id in 
    <foreach collection="list" item="abc" open="(" close=")" separator=","> 
        #{abc}  <!-- 输出结果为集合list中的所有元素的遍历例如Integer泛型的集合:(4,3,2) -->
    </foreach> 
</select>

sql,include 标签

  • 某些 SQL 片段如果希望复用,可以使用定义这个片段
<sql id="mysql">  <!-- 复用块 -->
    id,accin,accout,money 
</sql>
  • 在或或或中使用引用
<select id=""> 
    select 
    <include refid="mysql"></include> 
    from log
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值