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解决方案,正以前所未有的姿态,重新定义视频创作的边界,赋能万千用户与企业,共创视觉盛宴。 打破平台壁垒,实现无缝衔接 …...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
