MyBatis 入门之动态 SQL
文章目录
- 一、什么是动态 SQL
- 二、MyBatis 中的动态 SQL 标签
- 三、动态 SQL 的使用示例
- 四、总结
在 Java 开发中,MyBatis 是一个非常流行的持久层框架,它提供了强大的 SQL 映射功能和动态 SQL 支持。动态 SQL 可以根据不同的条件动态地生成 SQL 语句,使得我们在处理复杂的数据库查询和更新操作时更加灵活和高效。本文将介绍 MyBatis 中的动态 SQL,并通过示例代码帮助大家快速入门。
一、什么是动态 SQL
动态 SQL 是指在 SQL 语句中包含一些逻辑判断和变量,根据不同的条件动态地生成不同的 SQL 语句。在 MyBatis 中,动态 SQL 是通过使用各种标签和表达式来实现的。这些标签和表达式可以根据传入的参数值来决定是否生成相应的 SQL 片段,从而实现动态的 SQL 语句生成。
二、MyBatis 中的动态 SQL 标签
MyBatis 提供了以下几种常用的动态 SQL 标签:
- if 标签:用于根据条件判断是否生成 SQL 片段。如果条件成立,则生成相应的 SQL 片段;否则,不生成。
<select id="findUsersByCondition" parameterType="User" resultType="User">select * from user<where><if test="username!= null">and username = #{username}</if><if test="age!= null">and age = #{age}</if></where>
</select>
在上面的代码中,findUsersByCondition
方法根据传入的 User
对象的 username
和 age
属性的值来动态生成 SQL 语句。如果 username
不为空,则在 SQL 语句中添加 and username = #{username}
条件;如果 age
不为空,则添加 and age = #{age}
条件。
2. choose、when、otherwise 标签:用于实现类似 switch-case-default
的逻辑。当有多个条件需要判断时,可以使用 choose
标签来包裹多个 when
标签和一个可选的 otherwise
标签。
<select id="findUsersByCondition" parameterType="User" resultType="User">select * from user<where><choose><when test="username!= null">and username = #{username}</when><when test="age!= null">and age = #{age}</when><otherwise>and gender = 'male'</otherwise></choose></where>
</select>
在上面的代码中,如果 username
不为空,则生成 and username = #{username}
条件;如果 age
不为空,则生成 and age = #{age}
条件;如果都不满足,则生成 and gender = 'male'
条件。
- foreach 标签:用于遍历集合类型的参数,并根据遍历的结果生成 SQL 片段。
<select id="findUsersByIds" parameterType="java.util.List" resultType="User">select * from user<where><if test="ids!= null and ids.size > 0">id in<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach></if></where>
</select>
在上面的代码中,findUsersByIds
方法根据传入的 ids
列表参数来动态生成 SQL 语句。如果 ids
不为空且长度大于 0,则在 SQL 语句中添加 id in (...)
条件,并使用 foreach
标签遍历 ids
列表,将每个 id
值作为参数传入。
- trim、where、set 标签:
trim
标签可以用来在 SQL 片段的前后添加或删除特定的字符串,并可以控制是否在条件存在时添加连接符(如and
、or
)。where
标签用于在 SQL 语句中添加WHERE
关键字,并自动处理条件前面的多余连接符。set
标签用于在 SQL 语句中添加SET
关键字,并自动处理条件后面的多余逗号。
<update id="updateUser" parameterType="User">update user<set><if test="username!= null">username = #{username},</if><if test="age!= null">age = #{age},</if><if test="gender!= null">gender = #{gender}</if></set><where>id = #{id}</where>
</update>
在上面的代码中,updateUser
方法根据传入的 User
对象的属性值来动态生成 SQL 语句。set
标签用于设置更新的字段,如果某个属性不为空,则将其添加到 SET
子句中,并在后面添加逗号。where
标签用于添加 WHERE
条件,确保只更新指定的用户。
三、动态 SQL 的使用示例
下面通过一个完整的示例来演示 MyBatis 中动态 SQL 的使用。假设我们有一个用户管理系统,需要根据不同的条件查询用户信息,并可以更新用户的信息。
- 首先,创建一个
User
实体类:
public class User {private Integer id;private String username;private Integer age;private String gender;// 省略 getter 和 setter 方法
}
- 然后,创建一个
UserMapper
接口:
public interface UserMapper {List<User> findUsersByCondition(User user);void updateUser(User user);
}
- 接着,在
UserMapper.xml
文件中编写 SQL 映射语句:
<mapper namespace="com.example.UserMapper"><select id="findUsersByCondition" parameterType="User" resultType="User">select * from user<where><if test="username!= null">and username = #{username}</if><if test="age!= null">and age = #{age}</if><if test="gender!= null">and gender = #{gender}</if></where></select><update id="updateUser" parameterType="User">update user<set><if test="username!= null">username = #{username},</if><if test="age!= null">age = #{age},</if><if test="gender!= null">gender = #{gender}</if></set><where>id = #{id}</where></update>
</mapper>
- 最后,在测试类中调用
UserMapper
的方法:
public class MyBatisTest {public static void main(String[] args) throws IOException {// 加载 MyBatis 配置文件String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获取 SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();try {// 获取 UserMapper 接口的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 查询用户信息User user = new User();user.setUsername("admin");user.setAge(30);List<User> users = userMapper.findUsersByCondition(user);for (User u : users) {System.out.println(u);}// 更新用户信息User updateUser = new User();updateUser.setId(1);updateUser.setUsername("updatedAdmin");updateUser.setAge(35);userMapper.updateUser(updateUser);// 提交事务sqlSession.commit();} finally {// 关闭 SqlSessionsqlSession.close();}}
}
在上面的示例中,我们首先通过 SqlSessionFactoryBuilder
构建了一个 SqlSessionFactory
,然后从 SqlSessionFactory
中获取了一个 SqlSession
。接着,通过 SqlSession
获取了 UserMapper
接口的代理对象,并调用了 findUsersByCondition
和 updateUser
方法来查询和更新用户信息。
四、总结
MyBatis 的动态 SQL 功能使得我们在处理复杂的数据库查询和更新操作时更加灵活和高效。通过使用各种动态 SQL 标签,我们可以根据不同的条件动态地生成 SQL 语句,从而减少了硬编码 SQL 的工作量,提高了代码的可维护性和可读性。在实际开发中,我们可以根据具体的业务需求,灵活运用 MyBatis 的动态 SQL 功能,来实现更加复杂的数据库操作。
相关文章:
MyBatis 入门之动态 SQL
文章目录 一、什么是动态 SQL二、MyBatis 中的动态 SQL 标签三、动态 SQL 的使用示例四、总结 在 Java 开发中,MyBatis 是一个非常流行的持久层框架,它提供了强大的 SQL 映射功能和动态 SQL 支持。动态 SQL 可以根据不同的条件动态地生成 SQL 语句&#…...
软工大二学生待办事项:
该文章会常年更新!坚持! 2024.9.10 学习打包部署 记录睡眠 开始刷一个算法 巩固Git版本控制工具的使用 巩固利用Idea使用版本管理工具,SQl编写 抓紧时间了解公司营业执照 坚持到周末再打瓦!...
MongoDB延迟查询
在 MongoDB 中,查看副本集成员之间的副本延迟可以通过以下步骤进行: 使用 rs.status() 命令: 这个命令提供了副本集的详细状态信息,包括每个成员的延迟情况。在 MongoDB shell 中,你可以执行以下命令: rs.s…...
python如何获取html中的所有链接
在Python中,获取HTML页面中的所有链接通常可以通过使用第三方库如BeautifulSoup或lxml来完成。这里,我将提供一个使用BeautifulSoup库的示例,因为它简单易用且功能强大。 首先,你需要安装BeautifulSoup和requests库(如…...
79-java static修饰的类能不能被继承
Java中的类可以被final关键字修饰,表示这个类不能被继承。如果一个类被final修饰,那么这个类不能被继承,也就是说,final类不能被继承。 另一方面,static关键字可以用来修饰内部类,这样的内部类是静态内部类…...

MacOS wine中文乱码问题
安装wine 1、brew update 执行失败,提示安装如下 2、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow 3、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow 3、brew update 4、brew in…...

基于Springboot的鲜花销售网站的设计与实现
项目描述 这是一款基于Springboot的鲜花销售网站的系统 模块描述 鲜花销售系统 1、用户 登录 在线注册 浏览商品 鲜花搜索 订购商品 查询商品详情 水果分类查看 水果加购物车 下单结算 填写收货地址 2、管理员 登录 用户管理 商品管理 订单管理 账户管理 截图...

安卓玩机工具-----适合安卓机型的“搞机工具箱” 功能齐全 玩机推荐
搞机工具箱最新版是一款相当出色的电脑端手机工具箱软件,搞机工具箱正式版功能强劲,可以帮助用户不需要root就能够直接对手机进行调节,方便对手机进行更加全面的掌控,搞机工具箱便捷好用,只需要根据文字提示及自己的需…...
数据分析-17-时间序列分析的平稳性检验
1 什么是时间序列 时间序列是一组按时间顺序排列的数据点的集合,通常以固定的时间间隔进行观测。这些数据点可以是按小时、天、月甚至年进行采样的。时间序列在许多领域中都有广泛应用,例如金融、经济学、气象学和工程等。 时间序列的分析可以帮助我们理解和预测未来的趋势和…...
Unity3D Android多渠道极速打包方案详解
在移动应用开发过程中,特别是在使用Unity3D进行Android游戏或应用开发时,多渠道打包是一个常见且重要的需求。不同的渠道(如Google Play、华为应用市场、小米应用商店等)可能需要不同的配置和包名,手动进行这些操作既耗…...
数据库中的主键和外键分别是什么意思?
让我们来聊聊数据库设计中非常重要的两个概念——主键(Primary Key)和外键(Foreign Key)。这两个概念对于保证数据的一致性和完整性至关重要。 主键(Primary Key) 主键是一个表中的一个或一组字段&#x…...
HTML5中`<ul>`标签深入全面解析
在HTML5的广阔天地里,<ul>标签作为无序列表的代言人,扮演着举足轻重的角色。它不仅能够整洁地罗列信息,还通过丰富的属性和样式选项,为网页设计师提供了无限的创意空间。本文将深入剖析<ul>标签的内核,详细…...

MongoDB日志级别
日志 查看当前的日志级别 根据你提供的 MongoDB 命令结果,命令 db.adminCommand({ getParameter: "logComponentVerbosity" }) 返回了 "ok" : 0,这意味着命令执行失败,没有成功获取到日志级别的配置信息。错误信息 &quo…...
Softmax回归--分类--有监督
输出和类别的维度一样。 一、当我们想将先线性层的输出直接视为概率,存在一些问题: 1.不能限制输出数字总和为1。 2.不能保证都是正数。 所以会使用softmax进行归一化。 二、交叉熵损失 交叉熵是一个衡量两个概率分布之间差异的很好的度量࿰…...

Jenkins生成html报告
下载插件 1.需要下载插件 html Publisher plugins 2.下载Groovy(设置css样式),默认没有css样式 在Job配置页面,增加构建步骤Execute system Groovy script,在Groovy Command中输入上面命令,即可: System.…...
牛客——查找字符串
B-你好,这里是牛客竞赛_牛客周赛 Round 59 (nowcoder.com) 返回值是子串或字符在 string 对象字符串中的位置 #include <bits/stdc.h> using namespace std; int T; string s; int main() { cin >> T; while(T --) { cin >>…...

感恩 各位老师们!和滋养你的人在一起,确实很重要——早读(逆天打工人爬取热门微信文章解读)
感恩 各位老师们 引言Python 代码第一篇 洞见 和滋养你的人在一起,确实很重要第二篇 一天 风云突变结尾 (不是 现在网上在呢么各种图都有 哈哈哈) 引言 今天是什么特殊的日子吗? 没错 教师节 说起这个教师节 我觉得大家更要记住…...

StorageSync数据缓存API
uni.setStorageSyncs参数:将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。 uni.setStorageSync函数里面写两个参数,分别是key和值,两个参数名称可以随便取,如果有同名的key,那么后面key的值会覆盖掉前面key的值…...

Guitar Pro 8.2.1 Build 32 永久中文破解解锁版
嗨,亲爱的吉他英雄们和音乐爱好者们! 今天,我要向你们安利一个让无数音乐人疯狂打Call的神奇软件——Guitar Pro 8.2!它不仅仅是个普通的乐谱编辑器,更是你音乐创作路上的超级助手。 软件介绍 Guitar Pro 8永久解锁版…...
视频编辑SDK解决方案,助力企业快速部署上线
美摄科技,作为移动视频编辑技术的领航者,凭借其强大的移动端视频编辑SDK解决方案,正以前所未有的姿态,重新定义视频创作的边界,赋能万千用户与企业,共创视觉盛宴。 打破平台壁垒,实现无缝衔接 …...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...