MyBatis 之三(查询操作 占位符#{} 与 ${}、like查询、resultMap、association、collection)
文章目录
- 1. 参数占位符 #{} 和 ${} 的区别
- 2. ${} 的优点
- 3. SQL 注入问题
- 4. like 查询
- 5. 返回字典映射:resultMap
- 6. 一对一查询:association
- 7. 一对多查询:collection
回顾一下,在上一篇 MyBatis 之二(增、删、改操作)中,学习了针对 MyBatis 的增、删、改操作三步走
- 在 mapper(interface)里面添加增删改方法的声明
- 在 XMl 中添加 增删改标签和对应的 sql 代码
- 在 **Mapper 中右键 Generate 点击 Test 生成测试类
本篇将学习用 MyBatis 进行数据库的查询相关操作
1. 参数占位符 #{} 和 ${} 的区别
使用 #{} 得到 JDBC 的代码【针对 Integer 类型】
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQVBHzxs-1676203852995)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675756664478.png)]](https://img-blog.csdnimg.cn/abfa2f3ec804407187880d7b718f2ebe.png)
使用 ${} 得到 JDBC 的代码【针对 Integer 类型】
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMvgcCR5-1676203852995)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675756687871.png)]](https://img-blog.csdnimg.cn/7a867e852a3f41478ee0b009e6d456b9.png)
使用 #{} 得到 JDBC 的代码【针对 String 类型】
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lRDfahIv-1676203852996)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675757137901.png)]](https://img-blog.csdnimg.cn/eee8050a3cc74723b2e33be88c273d16.png)
使用 ${} 得到 JDBC 的代码【针对 String 类型】出错了
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2GnK7MTE-1676203852996)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675757384910.png)]](https://img-blog.csdnimg.cn/df64747874e443e594e3695b834ed003.png)
#{} 和 ${} 区别:
- 定义不同:#{} 预处理;而 ${} 是直接替换
- 使用不同:#{} 适用于所有类型的参数匹配;但 ${} 只使用于数值类型
- 安全性不同:#{} 性能高,并且没有安全性问题;但 ${} 存在 SQL 注入的安全问题
代码如下
@Mapper
public interface UserMapper {// 根据用户 id 查询用户public Userinfo getUserById(@Param("id") Integer id);// 根据全面查询用户对象(非模糊查询)public Userinfo getUserByFullName(@Param("username") String username);}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 是设置要实现的接口的具体包名 + 类名-->
<mapper namespace="com.example.mybatisdome1.mapper.UserMapper"><!-- 根据 id 查询用户 --><select id="getUserById" resultType="com.example.mybatisdome1.model.Userinfo">select * from userinfo where id=${id}</select><!-- 根据全面查询用户对象(非模糊查询) --><select id="getUserByFullName" resultType="com.example.mybatisdome1.model.Userinfo">select * from userinfo where username=${username}</select></mapper>
@SpringBootTest
@Slf4j
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid getUserById() {Userinfo userinfo = userMapper.getUserById(1);log.info("用户信息:" + userinfo);}@Testvoid getUserByFullName() {Userinfo userinfo = userMapper.getUserByFullName("张三");log.info("用户信息:" + userinfo);}
}
2. ${} 的优点
使用 ${} 可以实现排序查询
当传递的是一个 SQL 关键字 (SQL 命令 ,例如 desc)的时候,只能使用 ${} ,此时如果使用 #{} 就会认为传递的为一个普通的值,会给这个值加上单引号,这样就识别不出来 SQL 命令了,所以执行就会报错
使用 ${} 注意:因为使用 ${} 会存在 SQL 注入的问题,所以当不得不使用 ${} 时,那么一定要在业务代码中,对传递的值进行安全校验(当代码走到 Mapper 这一层时就必须要执行了,所以一定要在业务代码中,也就是 Controller 这一层对传递过来的 order 进行安全效验,不但要判断是否为 null,还要判断是不是 desc 或 asc,如果都不是代码就不要往下执行)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hwRv8g97-1676203852997)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675758827267.png)]](https://img-blog.csdnimg.cn/d220ee62c4274375ae59449b56bc3332.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X6a5i5tB-1676203852997)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675758847571.png)]](https://img-blog.csdnimg.cn/735847b090e04fdeac1ed4519beac8a7.png)
3. SQL 注入问题
当账号密码正确时,可以查询到用户信息
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMgcTs2l-1676203852998)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675760364205.png)]](https://img-blog.csdnimg.cn/f360aa7b3f33443b97b2237a56901461.png)
如果是 SQL 注入时
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bx7weRAc-1676203852998)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675761132558.png)]](https://img-blog.csdnimg.cn/dc47b6448e5140fcb0aec94ae537a0d1.png)
4. like 查询
使用 #{} 报错,但使用 ${} 在业务层的值又不能穷举 (如果使用 ${} 必须列出所有可能,比如前面的 order 只有 desc 或 asc 两种可能所以可以使用 ${},但这里如果是 username 不可能列举所有可能,所以不能使用 ${})
所以就可以使用 concat() 进行拼接
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bbqo7JtH-1676203853001)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675762375261.png)]](https://img-blog.csdnimg.cn/52138acfa67a49b28613ebb4e38641fa.png)
5. 返回字典映射:resultMap
前面在xml 的 标签中写返回类型 resultType 时,直接就是定义到某个实体类就行,但这种情况只适用于字段名称和程序中属性名相同的情况下,这种就是写起来方便
但如果是字段名称和属性名不同时,继续使用 resultType 就会报错,此时就要使用 resultMap 来配置映射
在一对一、一对多关系中可以使用 resultMap 映射并查询数
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZEtWN7Ms-1676203853002)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675763776043.png)]](https://img-blog.csdnimg.cn/f7d5407a061e47aab0db6ce56892f068.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5m9OJ4Ts-1676203853002)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675763677139.png)]](https://img-blog.csdnimg.cn/3025c63e78864fc893804d148a61371a.png)
6. 一对一查询:association
进行一对一查询,需要使用 association 标签,表示一对一的结果映射,其中
- property 属性:指定其中所要一对一的那个属性
- resultMap 属性:指定那个属性所关联的结果集映射
- columnPrefix 属性:用来解决多表中相同字段数据覆盖的问题
一篇文章对应一个作者
(1)在 model 文件夹中创建 ArticleInfo 文章的实体类(一对一查询,注意加上属性 userInfo 作者)
@Data
public class ArticleInfo {private int id;private String title;private String content;private String createtime;private String updatetime;private int uid;private int rcount;private int state;private UserInfo userInfo;
}
(2)在 Mapper 文件中创建 ArticleMapper 根据文章 id 获取文章
@Mapper
public interface ArticleMapper {// 根据文章 id 获取文章public ArticleInfo getArticleById(@Param("id") Integer id);}
(3)在resources/mybatis 中写 ArticleMapper.xml 实现 (2)中的接口
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 是设置要实现的接口的具体包名 + 类名-->
<mapper namespace="com.example.mybatisdome1.mapper.ArticleMapper"><resultMap id="BaseMap" type="com.example.mybatisdome1.model.ArticleInfo"><id column="id" property="id"></id><result column="title" property="title"></result><result column="content" property="content"></result><result column="createtime" property="createtime"></result><result column="updatetime" property="updatetime"></result><result column="uid" property="uid"></result><result column="rcount" property="rcount"></result><result column="state" property="state"></result><association property="userInfo"resultMap="com.example.mybatisdome1.mapper.UserMapper.BaseMap"columnPrefix="u_"></association></resultMap><select id="getArticleById" resultMap="BaseMap">select a.*,u.id u_id,u.username u_username,u.password u_password from articleinfo a left join userinfo u on a.uid = u.id where a.id = #{id}</select>
</mapper>
(4)生成测试类
@SpringBootTest
@Slf4j
class ArticleMapperTest {@Resourceprivate ArticleMapper articleMapper;@Testvoid getArticleById() {ArticleInfo articleInfo = articleMapper.getArticleById(1);log.info("文章详情:" + articleInfo);}
}
运行程序发现 userInfo 中属性没有查询到,这是因为前面写的 UserMapper.xml 中 写的 resultMap 有问题,要把所有属性都映射上
(5)修改 UserMapper.xml 中的 resultMap
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-giqJQCjE-1676203853002)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675819795845.png)]](https://img-blog.csdnimg.cn/337336bdf88f4e73ba189ba3396d9979.png)
(6)运行程序
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C2VQ0khc-1676203853003)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675822003612.png)]](https://img-blog.csdnimg.cn/446012af5354427d9ebf582b2b320630.png)
7. 一对多查询:collection
和一对一 标签类似,一对多也需要标签 ,来表示一对多的结果映射
其中也是需要设置 property(对象中的属性名)、resultMap(映射对象对应的字典)、columnPrefix(一般不要省略,解决了多张表中相同字段查询数据覆盖的问题)
一个用户多篇文章
(1)在实体类 UserInfo 中添加多篇文章的属性
@Data
public class UserInfo {private Integer id;private String name;private String password;private String photo;private String createtime;private String updatetime;private int state;private List<ArticleInfo> artlist;
}
(2)在 UserMapper 接口中写出查询用户及用户发表的所有文章的方法
@Mapper
public interface UserMapper {// 查询用户及用户发表的所有文章public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);}
(3)在 UserMapper.xml 中实现接口中的方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 是设置要实现的接口的具体包名 + 类名-->
<mapper namespace="com.example.mybatisdome1.mapper.UserMapper"><resultMap id="BaseMap" type="com.example.mybatisdome1.model.UserInfo"><!-- 主键映射 --><id column="id" property="id"></id><!-- 普通属性映射 --><result column="username" property="name"></result><result column="password" property="password"></result><result column="photo" property="photo"></result><result column="createtime" property="createtime"></result><result column="updatetime" property="updatetime"></result><result column="state" property="state"></result><collection property="artlist"resultMap="com.example.mybatisdome1.mapper.ArticleMapper.BaseMap"columnPrefix="a_"></collection></resultMap><!-- 查询用户及用户发表的所有文章 --><select id="getUserAndArticleByUid" resultMap="BaseMap">select u.*,a.id a_id,a.title a_title,a.content a_content,a.createtime a_createtime,a.updatetime a_updatetimefrom userinfo u left join articleinfo a on u.id = a.uid where u.id = #{uid}</select></mapper>
(4)生成测试方法

运行程序

相关文章:
MyBatis 之三(查询操作 占位符#{} 与 ${}、like查询、resultMap、association、collection)
文章目录1. 参数占位符 #{} 和 ${} 的区别2. ${} 的优点3. SQL 注入问题4. like 查询5. 返回字典映射:resultMap6. 一对一查询:association7. 一对多查询:collection回顾一下,在上一篇 MyBatis 之二(增、删、改操作&am…...
【云原生之Docker实战】使用Docker部署Web在线聊天室Rocket.Chat
【云原生之Docker实战】使用Docker部署Web在线聊天室Rocket.Chat 一、Rocket.Chat介绍二、检查本地系统环境1.检查系统版本2.检查docker版本3.检查docker状态4.检查docker compose版本三、下载Rocket.Chat镜像四、部署Rocket.Chat1.创建部署目录2.编辑docker-compose.yaml文件3…...
阿里一面:谈一下你对DDD的理解?2W字,帮你实现DDD自由
说在前面 在微服务的应用开发中,DDD 用得越来越普及。 在40岁老架构师 尼恩的读者交流群(50)中,DDD是一个非常、非常高频的交流话题。 最近,有小伙伴面试阿里时,遇到一个面试题: 谈谈你对DDD的理解? 小伙…...
嵌入式Linux入门级板卡的神经网络框架ncnn移植与测试-米尔i.MX6UL开发板
本篇测评由电子发烧友的优秀测评者“ALSET”提供。 米尔 MYD-Y6ULX-V2 开发板,基于 NXP i.MX6UL/i.MX6UL L处理器,该开发板被米尔称之为经典王牌产品。本次测试目标是在此开发板上进行神经网络框架ncnn的移植与测试开发,测试ncnn在此开发板上…...
扬帆优配|杠杆资金重仓股曝光,3只科创板股获多路资金青睐
到2月16日,科创板融资余额环比前一日削减1104.16万元,其间,23股融资余额环比添加超千万元,融资净买入居前的有晶科动力、诺诚健华、爱博医疗等。 到2月16日,市场融资余额算计1.48万亿元,较前一交易日削减27…...
资讯汇总230217
230217 22:48 【美联储理事鲍曼:美国通胀仍旧太高】美联储理事鲍曼表示,美国通胀仍旧太高;美国当前的经济数据不一致,不同寻常的低失业率是一个好迹象;让通胀回到目标还有很长的路要走;需要继续加息&#x…...
前置知识- 初值问题、ode 系列函数的用法、刚性 (stiff) 方程简介、高阶微分方程的降阶
1.1.4 龙格一库塔法 将向前欧拉法写成式 (1-37) 的形式, 可以看出它实际上利用了 f ( x , u ) f(x, u) f(x,u) 在 x n...
# AutoSar一文概览
1.什么是AutoSar AUTOSAR全称为“AUTomotive Open System ARchitecture”,译为“汽车开放系统体系结构”;AUTOSAR是由 全球各大汽车整车厂、汽车零部件供应商、汽车电子软件系统公司联合建立的一套标准协议、软件架构。 2.为什么汽车行业要定义一个…...
分享88个HTML旅游交通模板,总有一款适合您
88个HTML旅游交通模板下载链接:https://pan.baidu.com/s/1pziNhgpC53h3KZy_a-aAFQ?pwdf99e 提取码:f99e Python采集代码下载链接:采集代码.zip - 蓝奏云 HTML5旅行公司旅行社网站模板 HTML5旅行公司旅行社网站模板是一款提供旅行服务的公司…...
C#中GDI+的矩形功能扩展
文章目录一、中心定位绘制图形1、矩形及椭圆中心定位2、圆的中心定位矩形二、圆角矩形三、收缩功能四、移动复制功能原文出处: https://haigear.blog.csdn.net/article/details/129060020GDI发展到GDI绘制函数中的参数往往都有矩形这个参数(除绘制直线和…...
数字经济活动题
讨论活动1-1:数字化 经济数字化(数据数字化,高速通信,大容量存储)将如何影响您所居住的国家?在网上搜索新闻文章(两三篇就够了),并讨论数字化如何影响经济、公共部…...
html 的相对路径和绝对路径
整篇文章是以 src 标签进行演示。 文章目录 一、相对路径 1、同级目录查找 2、上一级目录查找 3、下一级目录查找 二、绝对路径 一、相对路径 👵相对路径:从当前目录开始查找。 1、同级目录查找 写法: 1.1.直接写文件名字;…...
selenium进行QQ空间登录
一、selenium简要说明 selenium是基于浏览器自动化的一个模块,它能便捷的获取网站中动态加载的数据,和实现模拟登录、爬虫等操作 二、实现流程 2.1 selenium前置操作 1. 安装selenium模块 pip3 install selenium 2. 下载浏览器内核程序 注意࿱…...
SpringCloud(二)负载均衡服务调用Ribbon、服务接口调用OpenFeign案例详解
五、负载均衡服务调用Ribbon 技术版本Spring Cloud版本Hoxton.SR1Spring Boot版本2.2.2RELEASECloud Alibaba版本2.1.0.RELEASE Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源项目,主…...
大数据第一轮复习笔记(2)
Spark ./spark-submit --class com.kgc.myspark01.WordCount --master yarn --deploy-mode cluster /opt/myspark01-1.0-SNAPSHOT.jar 1.Client向YARN的ResourceManager申请启动Application Master。Client中创建SparkContext同时初始化中将创建DAGScheduler和TASKScheduler…...
LeetCode 2108. 找出数组中的第一个回文字符串
给你一个字符串数组 words ,找出并返回数组中的 第一个回文字符串 。如果不存在满足要求的字符串,返回一个 空字符串 “” 。 回文字符串 的定义为:如果一个字符串正着读和反着读一样,那么该字符串就是一个 回文字符串 。 示例 …...
第63章 SQL 快速参考教程
第63章 SQL 快速参考教程 SQL 语句语法AND / ORSELECT column_name(s) FROM table_name WHERE condition AND|OR conditionALTER TABLEALTER TABLE table_name ADD column_name datatypeor ALTER TABLE table_name DROP COLUMN column_name AS (alias)SELECT column_name AS …...
机器学习笔记
一 1.类型 有监督:分类、回归 无监督:聚类、降维 2.挑战: 过拟合:泛化能力弱 欠拟合:模型过于简单 二、 1.开发流程 数据收集->数据清洗->特征工程->数据建模 2.选择性能指标: 回归问题 均方根…...
L1-072 刮刮彩票
“刮刮彩票”是一款网络游戏里面的一个小游戏。如图所示: 每次游戏玩家会拿到一张彩票,上面会有 9 个数字,分别为数字 1 到数字 9,数字各不重复,并以 33 的“九宫格”形式排布在彩票上。 在游戏开始时能看见一个位置上…...
Delphi XE在Linux上开发桌面应用:从安装FMXLinux插件到第一个跨平台GUI程序
Delphi XE在Linux上开发桌面应用:从安装FMXLinux插件到第一个跨平台GUI程序 引言 对于熟悉Delphi的开发者来说,将Windows平台上的成熟应用迁移到Linux环境一直是个挑战。Delphi XE虽然支持Linux开发,但官方仅提供命令行应用的支持ÿ…...
智能家居控制中心:OpenClaw+Qwen3.5-9B语音指令中转
智能家居控制中心:OpenClawQwen3.5-9B语音指令中转 1. 为什么需要语音控制的智能家居中枢? 去年装修新房时,我装了十几款不同品牌的智能设备——从米家的灯泡到涂鸦的窗帘电机,再到HomeKit的温控器。每次想调整家居状态…...
C#频谱图振动传感器温度传感器数据采集绘制频谱图和时域图,并存储数据库存储时间200ms左右
C#频谱图振动传感器温度传感器数据采集绘制频谱图和时域图,并存储数据库存储时间200ms左右,可以进行历史频谱图和时域图回放,可以求的最大值并设置阈值报警可以导出报警最近在搞工业设备监控系统的时候,需要实时采集振动和温度数据…...
Genus水平共现网络分析:高效替代OTU的实战指南
1. 为什么需要Genus水平共现网络分析? 做微生物群落研究的朋友们应该都深有体会,OTU/ASV水平的共现网络分析简直就是个时间黑洞。我去年处理一个土壤微生物项目时,2000多个OTU的共现网络跑了整整8个小时,等结果的时候都能看完两集…...
从零掌握ComfyUI-WanVideoWrapper:AI视频制作工具实战指南
从零掌握ComfyUI-WanVideoWrapper:AI视频制作工具实战指南 【免费下载链接】ComfyUI-WanVideoWrapper 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-WanVideoWrapper 在数字内容创作领域,视频生成工具正经历着前所未有的技术革新。…...
解锁Ghidra:面向逆向工程师的二进制分析工具指南
解锁Ghidra:面向逆向工程师的二进制分析工具指南 【免费下载链接】ghidra_installer Helper scripts to set up OpenJDK 11 and scale Ghidra for 4K on Ubuntu 18.04 / 18.10 项目地址: https://gitcode.com/gh_mirrors/gh/ghidra_installer 剖析Ghidra核心…...
iPhone 抓包失败 4 种具体情况逐个解决方法
抓不到包这个描述太模糊了,在实际调试中,这句话至少对应四种完全不同的情况: 完全没有请求只有浏览器能抓到能抓到但 HTTPS 解不开能抓到但数据不完整 如果不先分清楚是哪一种,就会一直重复安装证书或改代理配置。一、先做一个验证…...
树莓派C语言工程建立
从原来例子程序中拷贝一个例子例如blink目录到myPrj目录下,再拷贝其他几个文件,最终示意如下:修改CMakeLists.txt 文件,去除add_subdirectory(…)语句和add_subdirectory_exclude_platforms(…)语句,在最后增加 add_su…...
RSA宣布与Microsoft扩大合作,进一步巩固公司在无密码身份安全领域的领导地位
创新合作开启安全、基于人工智能的员工身份验证新时代 RSA今日在RSAC 2026大会上宣布,将扩大对全新Microsoft 365 E7:The Frontier Suite解决方案的支持。这一新增支持结合了额外的无密码功能,在企业拥抱人工智能驱动的生产力未来之际&#…...
VSCode党必看!用轻量级方案玩转LaTeX:2024年TexLive+VSCode配置全攻略
VSCode党必看!用轻量级方案玩转LaTeX:2024年TexLiveVSCode配置全攻略 对于习惯在VSCode中高效编码的开发者而言,切换到传统LaTeX编辑器往往意味着要放弃熟悉的快捷键、扩展生态和流畅的代码体验。本文将带你用完全基于VSCode的轻量级方案构建…...
