MyBatis第七讲:MyBatis动态SQL

news/2024/11/24 1:33:50/

九、MyBatis动态SQL

9、1什么是动态SQL

动态 SQL 是 MyBatis 的强大特性之一。在 开发过程中,经常出现开发人员需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。

动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。

9、2if

if结构,类似Java中的判断结构,根据参数的情况,可以动态拼接SQL语句

<select id="findAll" resultMap="bookType" useCache="true">select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId<!--在SQL语句执行时,根据name的情况进行判定,满足时,会根据name进行模糊查询,不满足时,则执行查询所有数据--><if test="name!=null">where name like #{name}</if>
</select>

if结构也可以实现多个参数拼接,依据参数的不同,对SQL语句进行拼接

<select id="findAll" resultMap="bookType" useCache="true">select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId where 1=1<if test="name!=null">and name like #{name}</if><if test="price!=0">and price > #{price}</if>
</select>

9、3choose (when, otherwise)

在MyBatis中,只有if结构,没有if—else结构,为了满足这种需求,MyBatis设计了choose—when—otherwise结构,这个结构类似于Java中的switch—case—default结构。

<select id="findAll" resultMap="bookType" useCache="true">select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId where 1=1<!--动态SQL传参时,当满足条件时,只执行最先满足条件的when,都不满足时,执行otherwise中的拼接SQL语句--><choose><when test="name!=null and name!=''">and name like #{name}</when><when test="price>0">and price>#{price}</when><otherwise>order by price desc</otherwise></choose>
</select>

9、3where

在动态SQL中,因为参数的情况不同,需要灵活的组织条件,但是不论多少条件,都需要使用where条件进行筛选,但是有的时候我们在条件都不满足时,就没有必要加入where关键字

<select id="findAll" resultMap="bookType" useCache="true">select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId <where><if test="name!=null and num!=''">and name like #{name}</if><if test="price>0">and price > #{price}</if></where>
</select>

当if的条件满足时,动态SQL会自动匹配where关键字

9、4set

依照where标签的特性,MyBatis根据这种情况,又提供了set标签,在执行update语句时,可以配合set标签,依据if条件动态拼接SQL

<update id="updateBook" parameterType="com.demo.entity.Book">update book <set><if test="name!=null and name!=''">name=#{name}</if><if test="price>=0">price=#{price}</if></set>where id=#{id}
</update>

9、5trim

在MyBatis动态SQL中,还有比where和set更灵活的动态拼接方式,就是trim标签

<select id="findAll" resultMap="bookType" useCache="true">select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId <trim prefix="where" prefixOverrides="and"><if test="name!=null and num!=''">and name like #{name}</if><if test="price>0">and price > #{price}</if></trim>
</select>

trim标签共有四个属性

  • prefix:给SQL语句拼接的前缀,为 trim 包含的内容加上前缀
  • prefixOverrides:去除 SQL 语句前面的关键字或字符,该关键字或者字符由 prefixOverrides 属性指定
  • suffix:给SQL语句拼接的后缀,为 trim 包含的内容加上后缀
  • suffixOverrides:去除 SQL 语句后面的关键字或者字符,该关键字或者字符由 suffixOverrides 属性指定。

9、6foreach

在动态SQL中经常遇见需要多个值或多个参数进行组合操作,MyBatis在提供了类似Java中的循环操作,通过循环,实现动态SQL

<insert id="insertBook2" parameterType="list" keyProperty="id" useGeneratedKeys="true" >insert into book(name,price) values<!--使用动态SQL中的循环标签foreach,collection要循环的集合,item集合中存储内容的临时变量,separator值之间的分隔符号,open表示以什么符号开头,close表示以什么符号结束--><foreach collection="list" item="book" separator="," open="(" close=")">#{book.name},#{book.price}</foreach>
</insert>

使用 foreach 标签时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  • 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  • 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  • 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。

9、7bind

在MyBatis中,使用bind标签对内容进行特殊处理,将参数设置成为需要特殊处理的值

<select id="findAll" resultMap="bookType" useCache="true"><bind name="bookName" value="'%'+name+'%'"/>select b.id,b.name,b.price,l.lid,l.userId,l.bookId from book b left join log l on b.id=l.bookId <where><if test="name!=null and num!=''">and name like #{bookName}</if><if test="price>0">and price > #{price}</if></where>
</select>

http://www.ppmy.cn/news/520803.html

相关文章

压电陶瓷

作用&#xff1a; 1、压电陶瓷的原理是对这种陶瓷片施加压力还有存在一些拉力&#xff0c;导致它的两端会产生极性相反的一种电荷就是这样通过回路而变成了电流。 2、这种效应叫作压电效应&#xff0c;如果把这种压电陶瓷做成&#xff0c;在换能器放在水中&#xff0c;那么在…

python数字猜谜2.0

改进了一下数字猜谜&#xff1a; 开头&#xff0c;可选等级&#xff1a; import random guess -1 c 0 print("数字猜谜游戏&#xff01;") n input("选择等级 A B C&#xff1a;") if (n "A") or (n "a"):guess random.randint…

[进阶]junit单元测试框架详解

单元测试 就是针对最小的功能单元(方法&#xff09;&#xff0c;编写测试代码对其进行正确性测试。 以前是如何进行单元测试的&#xff1f;有什么问题&#xff1f; 只能在main方法编写测试代码&#xff0c;去调用其他方法进行测试。无法实现自动化测试&#xff0c;一个方法测…

图像的翻转

在OpenCV中&#xff0c;图像翻转是一种常见的图像处理操作&#xff0c;用于改变图像的方向或视角。它可以水平翻转图像、垂直翻转图像或同时进行水平和垂直翻转。 作用和意义&#xff1a; 数据增强&#xff1a;图像翻转是数据增强的一种方式&#xff0c;可以增加训练数据的多…

升级一下《单词猜谜》

网上的单词猜谜都是英文的&#xff0c;不会英语的头痛 于是&#xff0c;我把《单词猜谜》改成中文&#xff0c;并且加上了点新功能&#xff1a; import random as rdmc rdm.randint(1, 3)name1 input("你的名字叫什么&#xff1f;&#xff1a;") if c 1:turns1 …

【Arduino】arduino使用l298n的代码分享

一、接线 二、使用步骤 int Left_motor_go8; //左电机前进(IN1) int Left_motor_back9; //左电机后退(IN2) int Right_motor_go10; // 右电机前进(IN3) int Right_motor_back11; // 右电机后退(IN4) char getstr;int moshi 0; #include <SoftwareSerial.h>…

Arduino项目:简易电子琴

Arduino自制简易电子琴 Arduino无缘蜂鸣器引脚10正极GND负极项目使用了8个引脚分别连接8个引脚&#xff0c;并给每个引脚加了10KΩ的下拉电阻以稳定引脚上的电平 代码&#xff1a; #include "pitches.h"void setup() {// put your setup code here, to run once:pi…

使用Arduino与L298N(红板) 驱动直流电机

L298N 简介 L298N驱动模块&#xff0c;可以驱动2个直流电机&#xff0c;可分别实现正转&#xff0c;反转功能&#xff0e; Bom表 Arduino Uno * 1 L298N驱动模块 * 1 直流电机 * 2 9v 电池 * 1 跳线 若干 Arduino uno …