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

MyBatis 之三(查询操作 占位符#{} 与 ${}、like查询、resultMap、association、collection)

文章目录

  • 1. 参数占位符 #{} 和 ${} 的区别
  • 2. ${} 的优点
  • 3. SQL 注入问题
  • 4. like 查询
  • 5. 返回字典映射:resultMap
  • 6. 一对一查询:association
  • 7. 一对多查询:collection

回顾一下,在上一篇 MyBatis 之二(增、删、改操作)中,学习了针对 MyBatis 的增、删、改操作三步走

  1. 在 mapper(interface)里面添加增删改方法的声明
  2. 在 XMl 中添加 增删改标签和对应的 sql 代码
  3. 在 **Mapper 中右键 Generate 点击 Test 生成测试类

本篇将学习用 MyBatis 进行数据库的查询相关操作

1. 参数占位符 #{} 和 ${} 的区别

使用 #{} 得到 JDBC 的代码【针对 Integer 类型】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQVBHzxs-1676203852995)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675756664478.png)]

使用 ${} 得到 JDBC 的代码【针对 Integer 类型】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMvgcCR5-1676203852995)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675756687871.png)]

使用 #{} 得到 JDBC 的代码【针对 String 类型】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lRDfahIv-1676203852996)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675757137901.png)]

使用 ${} 得到 JDBC 的代码【针对 String 类型】出错了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2GnK7MTE-1676203852996)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675757384910.png)]

#{} 和 ${} 区别:

  1. 定义不同:#{} 预处理;而 ${} 是直接替换
  2. 使用不同:#{} 适用于所有类型的参数匹配;但 ${} 只使用于数值类型
  3. 安全性不同:#{} 性能高,并且没有安全性问题;但 ${} 存在 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)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X6a5i5tB-1676203852997)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675758847571.png)]


3. SQL 注入问题

当账号密码正确时,可以查询到用户信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMgcTs2l-1676203852998)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675760364205.png)]

如果是 SQL 注入时

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bx7weRAc-1676203852998)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675761132558.png)]


4. like 查询

使用 #{} 报错,但使用 ${} 在业务层的值又不能穷举 (如果使用 ${} 必须列出所有可能,比如前面的 order 只有 desc 或 asc 两种可能所以可以使用 ${},但这里如果是 username 不可能列举所有可能,所以不能使用 ${})

所以就可以使用 concat() 进行拼接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bbqo7JtH-1676203853001)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675762375261.png)]


5. 返回字典映射:resultMap

前面在xml 的 标签中写返回类型 resultType 时,直接就是定义到某个实体类就行,但这种情况只适用于字段名称和程序中属性名相同的情况下,这种就是写起来方便

但如果是字段名称和属性名不同时,继续使用 resultType 就会报错,此时就要使用 resultMap 来配置映射

在一对一、一对多关系中可以使用 resultMap 映射并查询数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZEtWN7Ms-1676203853002)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675763776043.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5m9OJ4Ts-1676203853002)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675763677139.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)]

(6)运行程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C2VQ0khc-1676203853003)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1675822003612.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. 返回字典映射&#xff1a;resultMap6. 一对一查询&#xff1a;association7. 一对多查询&#xff1a;collection回顾一下&#xff0c;在上一篇 MyBatis 之二&#xff08;增、删、改操作&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自由

说在前面 在微服务的应用开发中&#xff0c;DDD 用得越来越普及。 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;DDD是一个非常、非常高频的交流话题。 最近&#xff0c;有小伙伴面试阿里时&#xff0c;遇到一个面试题&#xff1a; 谈谈你对DDD的理解&#xff1f; 小伙…...

嵌入式Linux入门级板卡的神经网络框架ncnn移植与测试-米尔i.MX6UL开发板

本篇测评由电子发烧友的优秀测评者“ALSET”提供。 米尔 MYD-Y6ULX-V2 开发板&#xff0c;基于 NXP i.MX6UL/i.MX6UL L处理器&#xff0c;该开发板被米尔称之为经典王牌产品。本次测试目标是在此开发板上进行神经网络框架ncnn的移植与测试开发&#xff0c;测试ncnn在此开发板上…...

扬帆优配|杠杆资金重仓股曝光,3只科创板股获多路资金青睐

到2月16日&#xff0c;科创板融资余额环比前一日削减1104.16万元&#xff0c;其间&#xff0c;23股融资余额环比添加超千万元&#xff0c;融资净买入居前的有晶科动力、诺诚健华、爱博医疗等。 到2月16日&#xff0c;市场融资余额算计1.48万亿元&#xff0c;较前一交易日削减27…...

资讯汇总230217

230217 22:48 【美联储理事鲍曼&#xff1a;美国通胀仍旧太高】美联储理事鲍曼表示&#xff0c;美国通胀仍旧太高&#xff1b;美国当前的经济数据不一致&#xff0c;不同寻常的低失业率是一个好迹象&#xff1b;让通胀回到目标还有很长的路要走&#xff1b;需要继续加息&#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”&#xff0c;译为“汽车开放系统体系结构”&#xff1b;AUTOSAR是由 全球各大汽车整车厂、汽车零部件供应商、汽车电子软件系统公司联合建立的一套标准协议、软件架构。 2.为什么汽车行业要定义一个…...

分享88个HTML旅游交通模板,总有一款适合您

88个HTML旅游交通模板下载链接&#xff1a;https://pan.baidu.com/s/1pziNhgpC53h3KZy_a-aAFQ?pwdf99e 提取码&#xff1a;f99e Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 HTML5旅行公司旅行社网站模板 HTML5旅行公司旅行社网站模板是一款提供旅行服务的公司…...

C#中GDI+的矩形功能扩展

文章目录一、中心定位绘制图形1、矩形及椭圆中心定位2、圆的中心定位矩形二、圆角矩形三、收缩功能四、移动复制功能原文出处&#xff1a; https://haigear.blog.csdn.net/article/details/129060020GDI发展到GDI绘制函数中的参数往往都有矩形这个参数&#xff08;除绘制直线和…...

数字经济活动题

讨论活动1-1&#xff1a;数字化 经济数字化&#xff08;数据数字化&#xff0c;高速通信&#xff0c;大容量存储&#xff09;将如何影响您所居住的国家&#xff1f;在网上搜索新闻文章&#xff08;两三篇就够了&#xff09;&#xff0c;并讨论数字化如何影响经济、公共部…...

html 的相对路径和绝对路径

整篇文章是以 src 标签进行演示。 文章目录 一、相对路径 1、同级目录查找 2、上一级目录查找 3、下一级目录查找 二、绝对路径 一、相对路径 &#x1f475;相对路径&#xff1a;从当前目录开始查找。 1、同级目录查找 写法&#xff1a; 1.1.直接写文件名字&#xff1b;…...

selenium进行QQ空间登录

一、selenium简要说明 selenium是基于浏览器自动化的一个模块&#xff0c;它能便捷的获取网站中动态加载的数据&#xff0c;和实现模拟登录、爬虫等操作 二、实现流程 2.1 selenium前置操作 1. 安装selenium模块 pip3 install selenium 2. 下载浏览器内核程序 注意&#xff1…...

SpringCloud(二)负载均衡服务调用Ribbon、服务接口调用OpenFeign案例详解

五、负载均衡服务调用Ribbon 技术版本Spring Cloud版本Hoxton.SR1Spring Boot版本2.2.2RELEASECloud Alibaba版本2.1.0.RELEASE Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说&#xff0c;Ribbon是Netflix发布的开源项目&#xff0c;主…...

大数据第一轮复习笔记(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…...

3|射频识别技术|期末考试知识点|第3讲_RFID射频前端|重点题目

...

LeetCode 2108. 找出数组中的第一个回文字符串

给你一个字符串数组 words &#xff0c;找出并返回数组中的 第一个回文字符串 。如果不存在满足要求的字符串&#xff0c;返回一个 空字符串 “” 。 回文字符串 的定义为&#xff1a;如果一个字符串正着读和反着读一样&#xff0c;那么该字符串就是一个 回文字符串 。 示例 …...

第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.类型 有监督&#xff1a;分类、回归 无监督&#xff1a;聚类、降维 2.挑战&#xff1a; 过拟合&#xff1a;泛化能力弱 欠拟合&#xff1a;模型过于简单 二、 1.开发流程 数据收集->数据清洗->特征工程->数据建模 2.选择性能指标&#xff1a; 回归问题 均方根…...

L1-072 刮刮彩票

“刮刮彩票”是一款网络游戏里面的一个小游戏。如图所示&#xff1a; 每次游戏玩家会拿到一张彩票&#xff0c;上面会有 9 个数字&#xff0c;分别为数字 1 到数字 9&#xff0c;数字各不重复&#xff0c;并以 33 的“九宫格”形式排布在彩票上。 在游戏开始时能看见一个位置上…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...