当前位置: 首页 > article >正文

SpringBoot动态SQL

目录

 动态SQL【重点】

1、 SQL片段

2、if

3、where [重点]

4、 set

5、 foreach


 动态SQL【重点】

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。


自己话理解: 帮助我们拼接SQL

常见的动态SQL语法

  • SQL片段(官方不是在动态SQL章节)

  • where , if

  • set

  • foreach

  • trim

  • choose-when-otherwise

1、 SQL片段

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。

自己的话: 减少代码重复,主要用于抽取字段,表名等

    <!-- 将重复的SQL代码抽取成SQL片段,以供复用 -->
    
<sql id="userField">
        id,
        username,
        password,
        phone,
        create_time,
        money,
        sex
    </sql>
​
    <select id="findAll" resultType="User">
        select
            <!-- 引入片段 -->
            <include refid="userField"/>
        from
            tb_user
    </select>

2、if

if就是用来判断,主要用于判断要不要拼接对应的条件语句

-- 需求:查询用户,条件是money=1000,如果密码不为空,也根据密码查
select * from tb_user where money = 1000
select * from tb_user where money = 1000 and password= '123456'

UserMapper.java接口方法

public interface UserMapper {
    /**
     * 演示if动态sql
     */
    List<User> findByMap(HashMap<String,Object> map);
​
}

UserMapper.xml

    
<select id="findByMap" resultMap="userResultMap">
        <!-- #{}写map的key -->
        select
            <include refid="userFields"/>
        from
            tb_user
        where 
        <!-- username是map的key -->
        <if test="username != null and username != ''">
            and username = #{username}
        </if>
        <if test="password != null and password != ''">
            and password = #{password}
        </if>
    </select>

测试

    
@GetMapping("/map")
    @ResponseBody
    public R map(){
        HashMap<String, Object> map = new HashMap<>( );
        // map.put("password","123456");
        // map.put("username","Uzi");
        User user = userService.findByMap(map);
        if (user != null) {
            return R.ok(user);
        }
        return R.fail();
    }

注意: 通过application.yml添加日志,显示sql. 通过打印的sql来判断是否拼接成功

3、where [重点]

如果说只有if,可能会出现这么一种情况

SELECT * FROM tb_user WHERE

多出一个where关键词!!


所以我们需要一个智能的,有条件时帮我们拼接where关键词,没有条件查询时,不拼接where,并且去掉多余的and关键词,但是不会主动帮助拼接and

   <select id="findUserByWhere" resultType="User">
        select
            <include refid="userField"/>
        from
            tb_user
        <where>
            <if test="username != null and username != ''">
                and username = #{username}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
         </where>
    </select>

所以一般会where和if一起用

4、 set

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列

UserMapper.java接口方法

public interface UserMapper {
    int updateUser(User user);
}

UserMapper.xml

  
  <!-- set完成动态更新 -->
    <update id="updateUser">
        update tb_user
        <!-- set标签自动拼接SET关键词 -->
        <set>
            <!-- 会自动过滤最后一个, -->
            <!-- 特别注意,因为判断条件是!=null,基本不可能为null,所以将基本类型变为包装类 -->
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="phone != null">
                phone = #{phone},
            </if>
            <if test="createTime != null">
                create_time = #{createTime},
            </if>
            <if test="money != 0.0">
                money = #{money},
            </if>       
        </set>
        where id = #{id}
    </update>

测试

5、 foreach

场景: 批量删除

delete from tb_user where id in (1,2,3,...);
String sql = "delete from tb_user where id in (";
int iMax = idsArr.length - 1;// 最大下标
for (int i = 0; i < idsArr.length; i++) {
  int id = idsArr[i];
  sql += id;
  if (i != iMax) {
      sql += ",";
  } else {
      sql += ")";
  }
}

UserMapper.java

public interface UserMapper {
    // 为了演示动态sql foreach
    int deleteBatch(List<Integer> ids);
}

UserMapper.xml

    
<!-- 动态sql foreach -->
    <delete id="deleteBatch">
        delete from tb_user
        where id in
        <!--
           <foreach>开始循环,取出集合中的数据
           collection,要遍历的集合,此处必须写list
           item , 遍历得到结果,命名任意,但是下面#{}内的名字要和这里一致
        -->
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}  
        </foreach>
    </delete>

测试

    
// 批量删除
    @GetMapping("/delete/batch")
    // http://localhost:8888/delete?id=1&id=2&id=3
    public R deleteBatch(@RequestParam List<Integer> list){
        int i = userService.deleteBatch(list);
        if (i > 0) {
            return R.ok(i);
        }
        return R.fail();
    }


http://www.kler.cn/a/303002.html

相关文章:

  • Ceph 中PG与PGP的概述
  • DOCKER 镜像基础命令
  • 前端垂直居中的多种实现方式及应用分析
  • 《新智慧》期刊的征稿范围主要包括哪些方面?
  • Redis - 集群(Cluster)
  • 【算法】——二分查找合集
  • 第15-02章:理解Class类并获取Class实例
  • leetcode1.两数之和
  • 编写XBOX控制器实现鼠标键盘输入
  • Python | Leetcode Python题解之第400题第N位数字
  • Iceberg与SparkSQL写操作整合
  • 【IP协议】IP协议报头结构(上)
  • Entity Framework (EF)框架中三种主要的数据加载策略
  • 反序列化漏洞练习1
  • Java实现简易计算器功能(idea)
  • Node.js发票识别接口助力企业实现发票的精准高效管理
  • golang学习笔记10——golang 的 Gin 框架,快速构建高效 Web 应用
  • 【Go】使用Goland创建第一个Go项目
  • 微服务杂谈
  • Android Studio打开Modem模块出现:The project ‘***‘ is not a Gradle-based project
  • 北京市推进车路城协同发展的创新实践与未来展望
  • 【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237
  • torchvision.transforms.ToPILImage()使用
  • 【工具】前端JavaScript代码在线执行器 方便通过网页 手机测试js代码
  • 基于深度学习的时空预测
  • 谷粒商城の缓存篇