SQL语句解析

SQL语句解析

  1. 左外连接
<select id="pageQuery" resultType="com.sky.vo.DishVO">
        select d.*,c.name as categoryName from dish d left outer join category c on d.category_id = c.id
    </select>

left outer join category c

  • left outer join 是 SQL 中的连接类型之一。它的作用是返回左边表(在这里是 dish 表)的所有记录,即使右边的表(category)没有匹配的记录,也会返回左边表的记录。
    • 左连接(LEFT JOIN):左连接会返回左表中的所有行,即使右表没有匹配的行。如果右表中没有匹配的行,那么右表的列会返回 NULL
    • 外连接(OUTER JOIN):指的是返回所有行,而不仅仅是有匹配行的记录。通常,如果没有匹配的行,右表的列值会是 NULL

在这里:

  • category c 表示右边的表是 category,并为它指定了别名 c
  • dish 表中选取所有字段(d.*),并从 category 表中选取 name 字段,重命名为 categoryName
  • 使用 LEFT OUTER JOINdish 表与 category 表通过 category_idid 进行连接。
    • 这意味着:即使某个菜品没有对应的分类(即 dish.category_idcategory 表中找不到匹配的 id),这个菜品的信息仍然会被返回,只是分类名称会显示为 NULL

模糊查寻

				<where>
            <if test="name != null and name != ''">
                and d.name like concat('%',#{name},'%')
            </if>
            <if test="categoryId != null">
                and d.category_id = #{categoryId}
            </if>
            <if test="status != null">
                and d.status = #{status}
            </if>
        </where>

1. <where> 标签的作用

<where> 标签用于自动为 SQL 语句添加 WHERE 子句,并根据 <if> 条件判断来动态构建查询条件。

  • 自动添加 WHERE 关键字:当你在 <where> 标签中添加多个 <if> 条件时,MyBatis 会自动添加 WHERE 关键字,并在每个条件之间添加 AND。如果第一个条件存在,则 MyBatis 会在 SQL 中添加 WHERE,之后的条件会自动加上 AND。如果没有任何条件满足,则 WHERE 关键字会被省略。

2. <if> 标签

每个 <if> 标签包含一个条件,当条件为 true 时,才会将对应的 SQL 片段添加到查询语句中。test 属性是条件判断的关键所在。

解析你的代码:

<where>
    <if test="name != null and name != ''">
        and d.name like concat('%',#{name},'%')
    </if>
    <if test="categoryId != null">
        and d.category_id = #{categoryId}
    </if>
    <if test="status != null">
        and d.status = #{status}
    </if>
</where>

2.1 模糊查询(like

  • and d.name like concat('%',#{name},'%') 这一行表示对 dish 表中的 name 字段进行模糊查询。这里使用了 like 操作符,它用来进行字符串匹配查找。
  • like 查询会根据给定的值在字段中查找符合条件的记录。% 是 SQL 中的通配符,表示匹配任意数量的字符。
    • concat('%',#{name},'%')concat 是一个字符串拼接函数,它会将 % 与传入的 name 参数连接起来。例如,如果 #{name} 的值是 "Pizza",则 concat('%', 'Pizza', '%') 会变成 "%Pizza%",这是一个模糊查询,表示查找包含 "Pizza" 的所有记录。
    • 模糊查询的例子
      • 假设 name 的值为 "Pizza",那么 SQL 语句会变成:

        
        and d.name like '%Pizza%'
        
        

        这表示查找 dish 表中所有名字中包含 "Pizza" 的记录。

2.2 categoryId != null

  • and d.category_id = #{categoryId}:这行表示当传入的 categoryId 不为 null 时,才会添加该条件。它会精确匹配 dish 表中的 category_id 字段。
    • 例如,如果 categoryId 的值为 2,那么 SQL 语句会变成:

      
      and d.category_id = 2
      
      
    • 如果 categoryIdnull,则这条条件不会被添加到 SQL 语句中。

2.3 status != null

  • and d.status = #{status}:这一行表示当 status 不为 null 时,才会加上该条件。它会精确匹配 dish 表中的 status 字段。
    • 例如,如果 status 的值为 1,那么 SQL 语句会变成:

      
      and d.status = 1
      
      
    • 如果 statusnull,则这条条件不会被添加到 SQL 语句中。

3. 总结模糊查询和 concat 的作用

  • 模糊查询(likelike 操作符用于在 SQL 中进行模糊匹配,可以用于查找包含指定字符的记录。使用通配符 %,可以在字符串的任意位置进行模糊匹配。
  • concat 函数concat 是一个字符串连接函数,通常用于将多个字符串拼接成一个字符串。在模糊查询中,concat('%', #{name}, '%') 用来动态构建包含通配符的查询条件,以便在 SQL 查询中实现模糊匹配。

动态sql

<select id="getSetmealIdByDishIds" resultType="java.lang.Long">
        select setmeal_id from setmeal_dish where dish_id in
        <foreach collection="dishIds" item="dishId" open="(" separator="," close=")">
            #{dishId}
        </foreach>
    </select>

这段代码是一个 MyBatis 的 动态 SQL 查询语句,它用于根据传入的 dishIds 查找 setmeal_id。动态 SQL 是 MyBatis 提供的一种灵活的方式,用于根据不同的查询条件动态构建 SQL 语句。下面我将逐行讲解这段代码的实现。

1. 方法签名与 select 标签:


<select id="getSetmealIdByDishIds" resultType="java.lang.Long">
    select setmeal_id from setmeal_dish where dish_id in

  • id="getSetmealIdByDishIds":这是该 SQL 映射语句的唯一标识符,你可以在 Java 代码中通过 sqlSession.selectList("getSetmealIdByDishIds", params) 调用它。
  • resultType="java.lang.Long":指定查询结果的类型,这里返回的是 Long 类型,表示查询结果将是 setmeal_id 的值。
  • SQL 查询语句的主体部分:select setmeal_id from setmeal_dish where dish_id in

2. <foreach> 标签:

<foreach collection="dishIds" item="dishId" open="(" separator="," close=")">
    #{dishId}
</foreach>

<foreach> 是 MyBatis 提供的一个标签,用于动态生成一个 IN 子句中的多个值。它会根据传入的 dishIds 集合,动态生成 SQL 语句的内容。

解释各个属性:

  • collection="dishIds":指定了 foreach 遍历的集合对象。dishIds 是传入的参数,可能是一个 List<Long> 或其他类型的集合。
  • item="dishId":指定集合中的每一个元素的名称。在这个例子中,每次遍历时,dishId 代表集合中的一个元素。
  • open="(":表示生成 SQL 中 IN 子句的开始部分,即 (
  • separator=",":表示在生成每个 dishId 值之间使用逗号 , 作为分隔符。
  • close=")":表示生成 SQL 中 IN 子句的结束部分,即 )

生成的 SQL:

假设传入的 dishIds[1, 2, 3],那么 <foreach> 会生成以下 SQL 部分:

sql
复制编辑
(1, 2, 3)

3. 完整 SQL 查询:

最终生成的 SQL 查询语句是:

sql
复制编辑
select setmeal_id from setmeal_dish where dish_id in (1, 2, 3)

  • 这里,setmeal_id 是要查询的字段,setmeal_dish 是表名,dish_id in (1, 2, 3) 表示查询所有 dish_id[1, 2, 3] 中的记录。

4. 动态 SQL 的作用:

  • <foreach> 标签 的作用是将 dishIds 集合中的元素动态地拼接到 SQL 查询中的 IN 子句。这样,无论你传入多少个 dishIds,MyBatis 都会自动生成相应的 SQL 查询。
  • 如果传入的 dishIds 集合为空,MyBatis 会生成一个空的 IN 子句(IN ()),这时查询可能会失败,因此通常需要在传入参数前进行有效性检查,确保集合不为空。

5. 总结:

这段代码实现了一个动态 SQL 查询,用于根据一组 dishIds 查找与之关联的 setmeal_id。其中,<foreach> 标签动态生成了 SQL 中 IN 子句的内容,使得可以根据不同的 dishIds 生成相应的 SQL 查询。动态 SQL 在处理这种变长查询条件时非常有用,可以避免手动拼接 SQL 字符串的麻烦,并且提高代码的可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值