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

MyBatis 动态 SQL:让 SQL 语句随条件灵活变化

目录

1. 动态SQL

1.1. if

1.1.1. 持久层接口添加方法

1.1.2. 映射文件添加标签

1.1.3. 编写测试方法

1.2. where

1.3. set

1.4. choose、when、otherwise

1.5. foreach

1.5.1. 遍历数组

1.5.2. 遍历Collection

1.5.3. 遍历Map

2. 总结


前言

本文来讲解MyBatis的动态SQL

集合代码和图片演示,旨在让大家更好的理解(๑•̀ㅂ•́)و✧

个人主页:艺杯羹🌿

系列专栏:本文ben'weben'wbenbeMyBbatis🚀

1. 动态SQL

一个查询的方法的Sql语句不一定是固定的
比如电影选片,根据不同要求,Sql语句就会添加不同的查询条件
如图:


此时就需要在方法中使用动态Sql语句

1.1. if

​<if>​标签内的Sql片段在满足条件后才会添加,用法为:<if test="条件">​。例如:根据不同条件查询用户:

1.1.1. 持久层接口添加方法

// 用户通用查询
List<User> findByCondition(User user);

1.1.2. 映射文件添加标签

<select id="findByCondition" parameterType="com.yibeigen.pojo.User" resultType="com.itbaizhan.pojo.User">select * from user where 1 = 1<if test = "username != null and username.length() != 0">and username like #{username}</if><if test = "sex != null and sex.length() != 0">and sex = #{sex}</if><if test="address != null and address.length() != 0">and address = #{address}</if>
</select>

1.1.3. 编写测试方法

@Test
public void testFindByCondition(){User user = new User();List<User> users1 = userMapper2.findByCondition(user);//users1.forEach(System.out::println);user.setUsername("%金%");List<User> users2 = userMapper2.findByCondition(user);users2.forEach(System.out::println);user.setAddress("北京");List<User> users3 = userMapper2.findByCondition(user);users3.forEach(System.out::println);
}
  1. if中的条件不能使用 && / ||,而应该使用 and / or
  2. if中的条件可以直接通过属性名获取参数POJO的属性值,并且该值可以调用方法。
  3. where后为什么要加1=1?
    任意条件都可能拼接到Sql中。如果有多个条件,从第二个条件开始前都需要加And关键字。加上1=1这个永久成立的条件,就不需要考虑后面的条件哪个是第一个条件,后面的条件前都加And关键字即可

1.2. where

​<where>​可以代替sql中的 where 1=1 和 第一个and
更符合程序员的开发习惯,使用<where>​后的映射文件如下:

if 标签放在 where 里

<select id="findByCondition" resultType="com.itbaizhan.user.User" parameterType="com.itbaizhan.user.User">select * from user<where><if test="username != null and username.length() != 0">username like #{username}</if><if test="sex != null and sex.length() != 0">and sex = #{sex}</if></where>
</select>

1.3. set

<set>​标签用在update语句中
借助<if>​,可以只对有具体值的字段进行更新
<set>​会自动添加set关键字,并去掉最后一个if语句中多余的逗号

<update id="update" parameterType="com.yibeigen.user.User">update user<set><if test="username != null and username.length() > 0">username = #{username},</if><if test="sex != null and sex.length() > 0">sex = #{sex},</if></set><where>id = #{id}</where>
</update>

1.4. choose、when、otherwise

这些标签表示多条件分支,类似JAVA中的switch...case
<choose>类似switch
<when>类似case
<otherwise>类似default
用法如下:

<select id="findByCondition" resultType="com.yibeigen.user.User" parameterType="com.yibeigen.user.User">select * from user<where><choose><when test="username.length() &lt; 5">username like #{username}</when><when test="username.length() &lt; 10">username = #{username}</when><otherwise>id = 1</otherwise></choose></where>
</select>

这段代码的含义为:
用户名 < 5 时使用 模糊查询
用户名 >= 5 并且 < 10 时使用 精确查询
否则查询id为1的用户

1.5. foreach

​<foreach>​类似 JAVA 中的for循环,可以遍历集合数组。<foreach>​有如下属性:

  • collection:遍历的对象类型
  • open:开始的sql语句
  • close:结束的sql语句
  • separator:遍历每项间的分隔符
  • item:表示本次遍历获取的元素,遍历List、Set、数组时表示每项元素,遍历map时表示键值对的值
  • index:遍历List、数组时表示遍历的索引,遍历map时表示键值对的键

1.5.1. 遍历数组

我们使用<foreach>​遍历数组进行批量删除

1. 持久层接口添加方法

void deleteBatch(int[] ids);

2. 映射文件添加标签

<delete id="deleteBatch" parameterType="int">delete from user<where><foreach open="id in(" close=")" separator="," collection="array" item="id" >#{id}</foreach></where>
</delete>

3. 编写测试方法

@Test
public void testDeleteBatch(){int[] ids = {5,8};userMapper.deleteBatch(ids);session.commit();
}


1.5.2. 遍历Collection

​<foreach>​遍历List和Set的方法是一样的,我们使用<foreach>​遍历List进行批量添加。

1. 持久层接口添加方法

void insertBatch(List<User> users);

2. 映射文件添加标签

<insert id="insertBatch" parameterType="com.yibeigen.user.User">insert into user values<foreach collection="list" item="user" separator=",">(null ,#{user.username},#{user.birthday},#{user.sex},#{user.address})</foreach>
</insert>

3. 编写测试方法

@Test
public void testInsertBatch(){User user1 = new User("程序员1", "男", "北京");User user2 = new User("程序员2", "女", "上海");List<User> users = new ArrayList();users.add(user1);users.add(user2);userMapper2.insertBatch(users);session.commit();
}

1.5.3. 遍历Map

我们使用<foreach>​遍历Map进行多条件查询

1. 持久层接口添加方法

/*** 多条件查询* @param map 查询的条件键值对 键:属性名 值:属性值* @return要给参数起一个参数名才能用!!!*/
List<User> findUser(@Param("queryMap") Map<String,Object> map);

2. 映射文件添加标签

<select id="findUser" parameterType="map" resultType="com.yibeigen.pojo.User">select * from user<where><foreach collection="queryMap" separator="and" index="key" item="value">-- 键是拼进来的,这个key和value是到时候会传进来的!!!-- ${} 是直接会加上的,#{},是会预编译的${key} = #{value}</foreach></where>
</select>

3. 编写测试方法

@Test
public void testFileUser(){Map<String, Object> queryMap = new HashMap<>();queryMap.put("sex", "男");queryMap.put("address", "北京");List<User> user = userMapper.findUser(queryMap);user.forEach(System.out::println);
}

2. 总结

现在就讲解完了动态SQL,希望对你有所帮助(๑•̀ㅂ•́)و✧

http://www.xdnf.cn/news/1141003.html

相关文章:

  • 【科研绘图系列】R语言绘制分组箱线图
  • 【锂电池剩余寿命预测】TCN时间卷积神经网络锂电池剩余寿命预测(Pytorch完整源码和数据)
  • 基于vue框架的房屋租赁系统设计与实现zrd8i(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 信息论至AI实践:交叉熵的原理全景与应用深度解析
  • 【后端】.NET Core API框架搭建(10) --配置163邮件发送服务
  • 数据统计模块后端架构解析:从Controller到SQL的ECharts数据对接实践
  • 实现库存显示和状态按钮的Question
  • 如何将 iPhone 备份到笔记本电脑?
  • 从 Spring Boot 2.x 到 Spring Boot 3.x:全面对比与快速上手指南
  • 解决“Module ‘./@ant-design/icons‘ does not exist in container”的Webpack微前端报错
  • 【unitrix】 6.8 加一运算(add_one.rs)
  • 【机器人】HOV-SG 开放词汇 | 分层3D场景图 | 语言引导机器人导航
  • 第16章 基于AB实验的增长实践——验证想法:AB实验实践
  • 【iOS】消息传递和消息转发
  • AI IDE冲击下JetBrains作死,IDEA埋订阅陷阱
  • C++---cout、cerr、clog
  • PYTHON日志神器nb_log详细介绍和使用说明
  • leetcode:单词接龙[图广搜][无权图找最短路径]
  • C# 转换(引用转换)
  • 超简单linux上部署Apache
  • React + Mermaid 图表渲染消失问题剖析及 4 种代码级修复方案
  • B 站关键词排名提高之账号互助术:矩阵助攻,流量起飞
  • OpenAI最强ChatGPT智能体发布:技术突破与应用前景分析
  • 前端项目利用Gitlab CI/CD流水线自动化打包、部署云服务
  • 乙烯丙烯酸酯橡胶市场报告:性能优势、行业现状与发展前景​
  • 【现有资料整理】灵枢 - 用于医学领域的 SOTA 多模态大语言模型
  • Java Set 集合详解:从基础语法到实战应用,彻底掌握去重与唯一性集合
  • Pythonday17
  • 群晖中相册管理 immich大模型的使用
  • C++ :vector的介绍和使用