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

动态SQL

前言

为什么要使用到 动态SQL这个知识点?

动态SQL 顾名思义 告诉我们 可以灵活的组装 sql 语句。我们可以根据具体的条件 ,调整sql 语句避免了 单一sql 语句的反复堆砌。【避免把sql 语句的条件写死】

动态SQL 被使用在哪?

  • mapper 映射文件

常用的动态SQL 中的元素

元素说明
<if>判断语句,用于单条件判断
<choose>(<when>,<otherwise>相当于Java 中的switch...case...default语句 用于多条件判断
<where>简化sql 语句中的where 条件判断
<trim>可以灵活的去除多余的关键字
<set>用于 sql 语句的动态更新
<foreach>循环语句,常用于in 语句 等列举条件

以下demo(案例)的项目准备

t_customer 表 的字段和 pojo 包下的 Customer 类的属性需要一一对应

导入依赖

  • mybatis 依赖 和 mysql-connector-java 依赖
  <dependencies><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency></dependencies>

mybatis-config 配置文件

配置 连接 数据库的环境,加载 映射文件

整个代码如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--    resourse 的值是 关于 数据库配置文件。含有url,username,password ,数据库驱动 等信息--><properties resource="db.properties"></properties><!--    environment 是一个环境,里面包含一个事务管理器,一个数据源 --><environments default="development"><environment id="development"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><!-- 配置数据源信息,主要有 数据库驱动,数据库连接地址,数据库用户名,数据库密码等               --><property name="driver" value="${driverClass}"></property><property name="url" value="${jdbcUrl}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property></dataSource></environment></environments><mappers><!-- 使用mapper 标签 指定mapper映射文件--><mapper resource="mapper/CustomerMapper.xml"/></mappers>
</configuration>

条件查询操作

mapper 接口中的方法

    //通过 顾客名字和工作 查询顾客信息List<Customer> findCustomerByNameAndJobs(Customer customer);

<if> 元素

应用场景:<if> 元素 类似于 Java 中的if 语句 ,常用于简单的条件判断

格式:<if test=" 表达式"> .....</if>

如果 表达式判断为true ,就 拼接,执行拼接后的sql 语句


demo(案例)

要求:在实际应用中,可以通过某个条件查询,例如 查找某个 客户的信息,可以通过姓名来查询。同时也可以不填姓名来查找客户。此时通过客户姓名来查询 客户信息,就是非必要条件。遇到这种情况,就可以通过 <if> 元素 实现

  •  <if> 元素 在mapper 映射文件的使用
    <select id="findCustomerByNameAndJobs" parameterType="fs.pojo.Customer" resultType="fs.pojo.Customer">select * from t_customer where 1=1<if test="username != null and username != ''">and username like concat('%',#{username},'%')</if><if test="jobs != null and jobs != ''">and jobs = #{jobs}</if></select>

      通过浏览代码,发现当使用 <if> 元素 时 只要 test 属性中的表达式为true,就会执行元素中的条件语句。但是在实际应用中,有时需要从多个选项中选择一个去执行。


<choose>, <when>,<otherwise> 元素

应用场景:当使用该元素时,可以理解为Java的 if(){...}else{....} 和 switch(){ case...default..}

格式

<choose>

<when test=" 表达式">....</when>

<otherwise >.....<otherwise>

</choose>

demo(案例)

  • 使用<choose>, <when>,<otherwise> 元素mapper 映射文件
  <select id="findCustomerByNameAndJobs" parameterType="fs.pojo.Customer" resultType="fs.pojo.Customer">select * from t_customer where 1=1<choose><when test="username != null and username != ''">and username like concat('%',#{username},'%')</when><when test="jobs != null and jobs != ''">and jobs = #{jobs}</when><otherwise>and phone is not null</otherwise></choose></select>

<where>,<trim> 元素

<where> 元素

在之前 demo案例中 都需要添加where 1=1 这个条件,而加入条件 ”1=1“ 后 ,既保证了where 后面的条件成立,有避免了where 后面第一个词是 and 或者 or 之类的关键字。但如果去掉这个条件,就直接和 and等其他的关键字相连。这就会导致问题。

因此这就是为什么要学习 <where> 元素 

<where> 元素 就相当于sql 语句中的where 

<trim> 元素
属性说明
prefx指定给sql 语句增加的前缀
prefixOverrides指定给sql 语句要去掉的前缀字符串
suffix指定给sql语句 增加的后缀
suffixOverrides指定给sql 语句要去掉后缀字符串

demo(案例)

<where>元素 在mapper 映射文件的使用

  <select id="findCustomerByNameAndJobs" parameterType="fs.pojo.Customer" resultType="fs.pojo.Customer">select * from t_customer <where><if test="username != null and username != ''">and username like concat('%',#{username},'%')</if><if test="jobs != null and jobs != ''">and jobs = #{jobs}</if></where>

注意:当使用<where> 元素,时,跟他紧邻的and 可以自由控制【删除或增加】

  • <trim> 元素 在mapper 映射文件的使用
  <select id="findCustomerByNameAndJobs" parameterType="fs.pojo.Customer" resultType="fs.pojo.Customer">select * from t_customer <trim prefix="where" prefixOverrides="and"><if test="username != null and username != ''">and username like concat('%',#{username},'%')</if><if test="jobs != null and jobs != ''">and jobs = #{jobs}</if></trim></select>

更新操作

<set>元素

mapper 接口中的方法

    //更新用户信息void updateCustomerBySet(Customer customer);

<set> 元素 相当于sql语句中的set 关键字

demo(案例)

  • <set> 元素 在mapper 映射文件的使用 
<update id="updateCustomerBySet" parameterType="fs.pojo.Customer">update t_customer<set><if test="username != null and username != ''">username = #{username},</if><if test="phone != null and phone != ''">phone = #{phone},</if><if test="jobs != null and jobs != ''">jobs = #{jobs},</if></set>

注意:当使用<set> 元素,时,最后一个 , 可以自由控制【删除或增加】


复杂查询操作

mapper 接口中的方法

    //批量查询顾客 信息List<Customer> findByArray(Integer [] ids);List<Customer> findByList( List<Integer> ids);List<Customer> findByMap( Map<String, Object> conditions );

<foreach>元素

为什么要学习<foreach>元素?

这里可以理解我们学习 Java中的 for 循环。我们之前学习 for 循环是为了解决 条件不变情况下的多次输出/打印。这里也是如此。如果客户表里有1000条数据,现在需要将id小于100的客户信息查询出来。这时候如果使用一条条 的sql 查询语句,显然是不现实的,因此借用 for循环的思想 ,循环打印 sql语句。

怎么学习<foreach>元素?

  • 了解如何使用 <foreach>元素 中的属性
属性名类型描述是否必填示例
collection字符串指定要遍历的集合或数组的名称。可以是方法参数名、对象属性名、listarraymap等。collection="list"<br>collection="user.ids"<br>collection="map.values"
item字符串为集合中的每个元素指定一个别名,用于在 <foreach> 内部引用。item="item"<br>item="id"<br>item="user"
index字符串为集合中的每个元素指定索引别名,用于在 <foreach> 内部引用索引。index="index"<br>index="i"
open字符串在 <foreach> 生成的 SQL 片段的开头添加的字符串。open="("<br>open="["
separator字符串在 <foreach> 生成的 SQL 片段中,每个元素之间插入的分隔符。separator=","<br>separator=" OR "
close字符串在 <foreach> 生成的 SQL 片段的结尾添加的字符串。close=")"<br>close="]"

重点:学习 <foreach>元素 主要是了解 元素中collection 属性值 array 数组 ,list 集合, 以及 map 键名


collection 属性值 array 数组
    <select id="findByArray" parameterType="java.util.Arrays" resultType="fs.pojo.Customer">select * from t_customer where id in<foreach collection="Customer" item="id" open="(" close=")" separator=",">#{id}</foreach></select>
collection 属性值,list 集合
    <select id="findByList" parameterType="java.util.List" resultType="fs.pojo.Customer">select * from t_customer where id in<foreach collection="list" item="id" open="(" close=")" separator=",">#{id}</foreach></select>
collection 属性值 map 键名
    <select id="findByMap" parameterType="java.util.Map" resultType="fs.pojo.Customer">select * from t_customer where jobs=#{jobs} and id in<foreach collection="ids" item="id" open="(" close=")" separator=",">#{id}</foreach></select>
疑问

为什么 要使用 map ?

在实际情况中,我们向 sql 语句中可能传递多个参数,这时候需要使用到map。 例如 我要查询性别为男 且 id<10 的客户信息

当使用map 时,怎么确定collection 属性值?

我们清楚 map 有一个很重要的知识点:key-value  

因此如果我们需要循环遍历某个字段,传递的参数必须要存在一个与之对应的key存入 map中.在下面的代码就是 我需要遍历的是id ,因此 collection 属性值为 ids

 List<Integer> ids = new ArrayList<>();ids.add(1);ids.add(2);ids.add(3);Map<String,Object> conditions = new HashMap<>();conditions.put("jobs","teacher");conditions.put("ids",ids);


http://www.mrgr.cn/news/92980.html

相关文章:

  • 【经验分享】Ubuntu vmware虚拟机存储空间越来越小问题(已解决)
  • Unity 打包后EXE运行出现Field to Load il2cpp的一种情况
  • [KEIL]单片机技巧 01
  • 2025-03-03 学习记录--C/C++-PTA 7-38 数列求和-加强版
  • 【监督学习】支持向量机步骤及matlab实现
  • Excel的行高、列宽单位不统一?还是LaTeX靠谱
  • 从DNS到TCP:DNS解析流程和浏览器输入域名访问流程
  • Vue盲区扫雷
  • 大语言模型学习
  • 【弹性计算】弹性裸金属服务器和神龙虚拟化(一):功能特点
  • 大语言模型学习--LangChain
  • GPIO及其应用
  • 【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景
  • 年后 总结
  • Ubuntu20.04下各类常用软件及库安装汇总(联想Y9000P24款)
  • 【Mac】git使用再学习
  • 《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》
  • CSS—text文本、font字体、列表list、表格table、表单input、下拉菜单select
  • Linux 基本命令
  • web第四天