mybatis动态SQL

    • 动态SQL
    • if标签
    • trim标签
      • if局限性
      • trim标签作用
    • where标签
    • set标签
    • foreach标签

动态SQL

动态SQL就是允许你xml写逻辑判断;if else for等等。
比如有些字段可填可不填;当不填就应该要有逻辑判断。不像我们前面写的代码都是必填。比如30个字段;你最后只填了10个字段;那么没填的就是默认值。而空和不传是不同的概念;这需要用到动态SQL判断。
比如:state默认是1;当这个字段传过来的是null和不传;区别是非常大
mybatis动态SQL_第1张图片
显然我们需要的state=1这种情况
mybatis动态SQL_第2张图片

if标签

if;判断。可以实现动态;同样的代码不同的输入信息产生的sql语句不同。
if效果演示:
实体类代码
mybatis动态SQL_第3张图片
mybatis动态SQL_第4张图片
这样子就不会出现没传state时生成的执行代码是:insert into userinfo(username,password,state) value(‘zhaoliu’,888886,null)

mybatis动态SQL_第5张图片
单元测试代码:
mybatis动态SQL_第6张图片

这里面的test条件还能搭配and和or使用:tset里的sex是传入对象的属性;并不是数据库里的字段

<if test="state!=null and state!='' ">

    </if>


<if test="state!=null or state!='' ">

    </if>

trim标签

if局限性

上面的if语句还是有局限性;当我所有的属性都是可填可不填。如下代码就会发现如果username是null;而password不是null。那么构造出来的SQL语句就是有问题的。逗号会在前面;这个逗号也没法省。

<insert id="addUser">
    insert into userinfo(
    <if test="username!=null">
        username
    if>
    <if test="password!=null">
        ,password
    if>
    <if test="state!=null">
        ,state
    if>
    
    ) values(
     <if test="username!=null">
        #{username}
    if>
     <if test="password!=null">
        ,#{password}
    if>
    <if test="state!=null">
        ,#{state}
    if>
    )

insert>

trim标签作用

String也有trim这样的一个方法;去除字符串左右两遍的空格
标签中有如下属性:
prefix:表示整个语句块,以prefix的值作为前缀
suffix:表示整个语句块,以suffix的值作为后缀
prefixOverrides:表示整个语句块要去除掉的前缀
suffixOverrides:表示整个语句块要去除掉的后缀
使用trim属性prefix、suffix;可以去前缀或者后缀。有才去掉;没有就不去掉;也不影响效果。
代码演示:
mybatis动态SQL_第7张图片

where标签

trim还是有局限性;当我是where语句时;如下:where你去没法处理;使用trim比较麻烦处理;如果两个语句但是不传参数;那么这个where就是多余的。假设你where分别写在里面;如果两个都传那还是生成错误的SQL语句

 select * from articleinfo where 
            <if test="id!=null and id>0">
                id=#{id}
            if>
              <if test="title!=null and title!=''">
                and title like concat('%',#{title},'%')
            if>

解决方案1:当前代码要修改得加个where 1=1;去掉前缀是and情况。虽然这种情况都不传参编译器会帮你优化的where 1=1;性能不存在问题;但是代码冗余

解决方案2:针对where做处理;如果where是后缀那我得使用trim去掉

解决方案3:根据你里面的内容;是否生成where。可以帮你自动去掉and前缀,但是不能去掉是and后缀

 select * from articleinfo 
    <where> 
            <if test="id!=null and id>0">
                id=#{id}
            if>
              <if test="title!=null and title!=''">
                and title like concat('%',#{title},'%')
            if>
    where>

set标签

set有什么用;和where类似的;修改要用set;里面的参数至少得有一个是要传的,不然就报错。不能全部参数都不传。都不传的话;那就在控制层上判断;一个参数都没有不去调用这个方法。
演示代码:

    <update id="updateByid" parameterType="com.example.demo.entity.UserEntity">
         update user
              <set>
                  <if test="username != null">
                      username=#{username},
                  if>
                  <if test="password != null">
                      password=#{password},
                  if>
              set>
            where id=#{id}

    update>

parameterType作用:例如

<update id="updateUser" parameterType="User">
  UPDATE users
  SET name = #{name},
      age = #{age},
      email = #{email}
  WHERE id = #{id}
update>

parameterType=“User” 表示传递给 SQL 语句的参数对象类型是 User。MyBatis 会自动将 User 对象的属性(如 name、age、email)映射到 SQL 语句中的相应位置(使用 #{} 占位符),从而实现参数传递和动态生成 SQL 语句。

标签也可以使⽤ 替换。

foreach标签

对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
item:遍历时的每⼀个对象
open:语句块开头的字符串
close:语句块结束的字符串
separator:每次遍历之间间隔的字符串
比如:需要批量删除或者增加
正常我们写的删除语句是;如下里面的123这里得换是集合的内容。
mybatis动态SQL_第8张图片
这里非常得注意id是来自集合;有可能list什么都不传;非常危险;如果你的写法构造出的SQL语句是 delete from articeinfo where id ;那就是相当于删库跑路的一个操作;会把表删的只剩下一张空表。所以我们在控制层处理;当什么都不传就不调用。不判断的话;遇到一些非法请求也很危险。

foreach标签使用:mybatis动态SQL_第9张图片
item取一个别名;遍历时的每一个对象是1、2、3。下面的#{aid}就能拿到1、2、3。括号也能放进open、close属性进行代替。
mybatis动态SQL_第10张图片

你可能感兴趣的:(spring,mybatis,sql,数据库)