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 的“九宫格”形式排布在彩票上。 在游戏开始时能看见一个位置上…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
