MyBatis进阶版

news2025/2/22 22:19:04

 本文有点难

目录

1.一些区分

1.1参数占位符#{}和${}

1.1.1SQL注入

1.1.2like查询

1.2resultType和resultMap

2.映射查询

2.1一对一表映射

2.2一对多表映射

3.动态SQL

3.1标签

3.2标签

3.3标签

3.4标签

3.5标签


1.一些区分

1.1参数占位符#{}和${}

①什么是#{}:

这个字符实际上是预编译处理,总的来说,就是当SQL在执行的过程中,mybatis会把其#{}替换为?,而通过PrepareStatement的set来实现赋值的操作。

 ②什么是${}:

这个字符实际上是字符直接替换符,也就是当SQL在执行过程中,mybatis会直接把${}所在的位置进行传入参数的赋值。

③传入数值类型对两者进行验证:
(1)#{}:
我们可以看到其实就是进行了个预处理操作,先将id预处理(或者称为预查询)为?,然后再进行进一步的处理。
(2)${}:
而这种参数的直接替换(我们也可以称其为即时查询),可能会带来越权查询和操作数据等问题,比如后面我们会讲到SQL的注入。
④传入字符串类型对两者进行验证:

(1)#{}:

(2)${}:

对于其是不支持带引号的字符串类型:

如果确实需要,那么我们手动加上引号:(这个时候会发现测试用例通过),即表明是可以的 ,但是这种做法是不推荐的,后面我们会讲为什么不推荐

 ⑤当传入的是SQL关键字的时候:

(1)#{}:

这个时候会报错,因为关键字会被当做传入的是一个普通的值。

sql及测试代码:

输出结果:(即关键字不会被识别)

(2)${}:

不会报错,可以成功运行,这也就说明当传入的是SQL关键字的时候,我们只能用${},而不能用#{}

sql及测试代码:

输出结果: 

但是!!!

值得注意的是在当我们只能使用${}的时候,我们一定要在业务代码中对传递的值来进行安全效验。下面的SQL注入就是这一点的一个体现。

1.1.1SQL注入

①什么是SQL注入:

实质上就是通过使用${},使用一些特殊的语句,来达到非法获取数据的目的。

②示例:(下面我们通过SQL注入来直接获得用户密码)

sql及测试代码:

 结果:(能够获取到用户的密码)

 结论:

因此由${}来注入很显然会引起SQL注入,这种是很不安全的,所以我们大多数时候能使用#{}就不会选择使用${},只有一些特定的SQL关键字如desc,asc这种才会使用${},如果实在迫不得已使用${}我们也要对传入的参数来进行安全校验。

1.1.2like查询

①什么是like查询?

这个问题应该很简单,就是我们之前在将sql中提到的泛查,根据一个字来查出整个用户

②注意:

这里的like查询是非常特殊的一个查询,怎么说呢?

使用#{}来进行查询会报错,而使用${}来查询在业务层的值又不能够穷举,验证非常麻烦,所以我们这里就直接示范#{}

下面我们来举个例子:

sql及测试:

 结果:

显然,这出现问题是很简单的,因为#{}会被替换成一个字符串 ,而在两个%里面的是不能带有字符串的,换句话来说,该查询语句实质上就变成了,select * from userinfo where username like='%'张'%'的形式,显然,这是不行的。

③正确用法:

引入cancat,这相当于是sql中的一个字符拼接语句,它的规则如下:

concat('%',#{},'%')就相当于把三个部分拼接在了一起。

sql及测试:

 结果如下:

1.2resultType和resultMap

之前我们就有说到,要是用到select进行查询的话,就必须添加属性resultType或者resultMap,那么这两者之间究竟有什么区别呢?我们下面就来谈谈。

①resultType:

(1)写法:(注意:需要写到返回类型所在的类)

 (2)缺点:(当数据库名字与字段名字不同的时候,我们通过查询,就不能够获取到对应的值)举个例子:

这个时候,在数据库中表示名字的字段是username,而在userInfo这个类中,定义的字段确是name,那么这个时候,当我们进行查找的时候,就不会返回对应的name属性。

数据库:

userinfo类:

测试:

 而就是为了解决这种问题,我们就引入了resultMap

②resultMap:

(1)写法:

注意:resultMap是写在Mapper标签下的,且这个标签必须写哪个属性,第一个属性是id,其它功能可以根据这个id来拿到这个 resultMap,第二个属性是type,就是写到映射对象所对应到的类。然后在这个resultMap标签下会有两个映射,一个是主键映射,主键映射的话就是<id column="" property=""></id>而在id这个标签内仍然有两个属性,column是示数据库表中的字段名,另外一个是property表示程序类中的字段名。另一个是普通映射,仍然是这两个属性来进行设置。<result column=""  property=""></result>标签中的属性和主键中的含义是一致的。

 (2)演示刚刚在resultType中出现的问题,是否被解决了:

 改进后就会返回BaseMap这个字典:

输出结果:(字段名不一致,但是仍然可以输出)

 (3)resultMap的优点:

a.字段名不一致时用来手动进行映射处理

b.可以用于多表查询

2.映射查询

2.1一对一表映射

①什么是一对一映射:

就是对于一个属性而言,它只与另一个表所在的属性有关系的映射。在这里,讲给大家演示有关于在博客系统中一个用户对应了一个博客账户的这样一一对应的关系,将在mybatis中实现这种映射关系。

②实战:

(1)我们查询articleinfo这个数据表的数据,并建立一个博客类与之对应:

建立博客类如下:

package com.example.mybatis.model;

import lombok.Data;
@Data
public class articleinfo {
    private Integer id;
    private String title;
    private String content;
    private String createtime;
    private String updatetime;
    private Integer uid;
    private Integer rcount;
    private Integer state;
    //因为要与用户表实现关联,所以我们这里创建一个UserInfo的属性
    private UserInfo userInfo;
}

(2)创建articleinfo对应的mapper接口和xml文件:(我们以根据文章名字获取文章对象为例)

ArticleinfoMapper接口:

package com.example.mybatis.mapper;

import com.example.mybatis.model.Articleinfo;
import com.example.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface ArticleinfoMapper {
    //根据文章id获取文章标题
    public Articleinfo getArticleById(@Param("id") Integer id);


}

ArticleinfoMapper.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">
<mapper namespace="com.example.mybatis.mapper.ArticleinfoMapper">
    <select id="getArticleById" resultType="com.example.mybatis.model.Articleinfo">
        select * from articleinfo where id=#{id};
    </select>


</mapper>

测试语句:

 结果:(虽然这个时候测试的结果是没有问题的,但是我们发现userInfo=null,即没有获取到userinfo对象,除此之外,我们还可以发现这个SQL语句并不是多表联查的语句)

 那么我们怎么才能得到这个对象呢?我们需要用resultMap来实现。

(3)用resultMap来实现:(不管列名的前缀来实现)

注意这个时候我们不仅需要把

a.Articleinfo类中每个属性与数据表的映射,还要把userInfo类中的每个属性与数据相映射:

b.利用一对一结果映射标签:

<association property="这是属性名"  resultMap="关联到某个mapper上"  columnPrefix="列名的前缀" ></association>

(这个时候我们先不管列名的前缀来实现)

 c.重写sql实现联合查询:

 此时结果:(实现了联查) 

(4)我们前面是没有使用列名的前缀来实现,好像也没有出现什么问题,这是因为如果两个表字段重名了,进行多表查询的时候,第一个值就会把第二的值来进行覆盖,我们下面来看看这个情况:(前缀是用来解决多表中相同字段数据覆盖的问题的)

我们修改userinfo表,将id值由1改为2

修改articileinfo中uid=2:

 这个时候我们再重复刚刚的测试,我们来看具体值:(我们可以看到这个时候userinfo中的id=1,而我们刚刚明明进行修改变成了2)这就表明如果我们联系的两个表中有相同的字段,那么后一个表中的该字段会被前一个表中的该字段给覆盖。

 所以我们怎么解决这个问题呢?我们列名的前缀来实现:

设置前缀就相当于把查询的结果给重命名了

使用重命名,使userinfo中的三个属性重命名为以u_开头的前缀 

输出结果:

这个时候就没有被覆盖了 

2.2一对多表映射

①什么是一对多映射:

一对多的关系,就是对于一个属性,它对映着多个其他的属性。举个例子,一个用户可以写多篇博客,这样就是一对多映射关系的一种体现

②与一对一映射的不同点:

(1)因为是一对多,所以我们在存储对象的时候就用list:(比如现在是一个用户,那么我们就在这个用户类中添加一个list)

(2)一对多的过程中使用的是collection标签,而里面的属性和一对一映射中都是一致的

 (3)测试输出结果:

测试:

  结果:

 正确!!!

3.动态SQL

①什么是动态SQL:

可以理解为动态的进行调节的SQL,我举个例子,如果前端给你返回了参数,那么就直接传入返回参数的值,如果没有传入参数,那么就返回全部的值。说白了,就是用来针对非必传参数这一问题的,除此之外,其还可以解决拼接时空格的问题,以及遗漏或者多加符号的问题。

官网定义:

mybatis – MyBatis 3 | 动态 SQL

②动态SQL的体现:

我们这里的动态SQL主要就从以下5个标签中来进行讲解。

3.1<if>标签

①作用:

用来判断一个参数是否有值,要是有值就返回里面的值,要是没有,就隐藏if中的sql

②格式:

<if test="表达式">

sql

</if>

举个实例:

<if test="username!=null">

username=#{username}

</if>

结果,如果为真,那么原SQL语句就会直接将其拼接上;如果为假,那么if中的sql就会被忽略。

③实战演练:

(1)不添加photo参数,直接忽略if标签内容:

sql及测试:

结果显示:

(2)添加photo的参数情况,拼接标签内容:

sql及测试:

  结果显示:

3.2<trim>标签

①作用:(其可以与其他标签进行搭配使用)

最主要的就是去掉SQL语句前后某个多余的字符。这里面有四个参数:

prefix:表示整个语句块,以prefix的值作为前缀

suffix:表示整个语句块,以suffix的值作为后缀

prefixOverrides:表示整个语句块要去除掉的前缀

suffixOverrides:表示整个语句块要去除掉的后缀

②格式:

<trim prefix="前缀符", suffix="后缀符", prefixOverrides="去除多余的前缀字符", suffixOverrides="去除多余的后缀字符">
	<if test="表达式">
		...
	</if>
...
</trim>

③实战演练:

(1)不添加photo内容情况:

sql及测试:

 输出结果:

 (2)添加所有的情况:

sql及测试:

 结果显示:

3.3<where>标签

①作用:

替代SQL语句中的where标签,如果满足即执行,不满足就忽略,同时它还可以自动去除最前面的and字符

②格式:

<where>

.....

</where>

③实战例子:

(1)输入某个id来进行查询该用户信息:

sql及测试:(执行到了where中的if字句)

 结果如下:

(2)不输入id看是否能查询到用户信息:(即输入为null)

sql及测试:

 结果如下:测试是失败了,但是却找到了所有的user

(3)测试去除最前面的and字符

sql及测试:

 结果如下:(and被自动去除掉了)

3.4<set>标签

①作用:

就是在修改sql所执行的操作,配合if来进行非必要输入的,同时它还可以自动去除最后一个英文逗号

②格式:

<set>

...

</set>

③实战示例:

(1)使用set标签来执行SQL:

sql及测试:

 结果:

数据库查看:

 (2)实现自动去除最后一个英文逗号:

sql及测试:

 结果:

3.5<foreach>标签

①作用:

是对集合进行循环使用的,常用于删除操作

collection:绑定方法参数中的集合,如 List,Set,Map或数组对象

item:遍历时的每一个对象

open:语句块开头的字符串

close:语句块结束的字符串

separator:每次遍历之间间隔的字符串

这里的open和close就有点类似于我们前面trim中prefix和suffix的作用

②格式:

<foreach collection="集合名" open="  " close="  " separator="  " item=" ">

...

</foreach>

③实战示例:

删除前的数据表:

sql及测试:(删除id为678的用户)

 结果:

并查看数据库:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28885.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CSS】表布局,浮动布局

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录表布局表层表标题(caption)border-collapse边框隐藏表大小table-layout(表宽度)vertical-align例…

你安全吗?丨虎云系统“后门”

作者&#xff1a;黑蛋 在电视剧《你安全吗&#xff1f;》中&#xff0c;马平川这个人物已经慢慢浮出水面&#xff0c;算是此部电视剧幕后的最大反派&#xff0c;他明面上是虎迫集团的技术总监&#xff0c;是虎云系统的负责人&#xff0c;开发者。背后却在泰曼达有着诈骗基地&a…

2022年11月21日13:32:00——T5——JS对象与Date日期函数

1、JavaScrip对象的使用&#xff1a; /** * 1、对象的声明赋值使用的是{}花括号&#xff0c;大括号 * 2、对象中的值以key:value的格式进行赋值&#xff0c;多个值中间使用【,】区分 * 3、获取对象中的值的方法需要通过[]并给与key名的方式获取&…

电脑怎么设置开机密码?简单几步给你的电脑“上锁”

在我们日常生活中&#xff0c;最常见的就是开机密码了&#xff0c;而电脑作为我们使用频率最高也是最复杂的设备&#xff0c;其安全性也是非常重要的&#xff0c;那么电脑怎么设置开机密码&#xff1f;那么今天我们就来说一说开机密码的设置方法&#xff01;为了更安全&#xf…

Essay写作字数怎么正确进行删减?

对于留学生来说&#xff0c;Essay写作伴随着整个留学生活。正因为留学生大量的Essay作业&#xff0c;不少留学生为了规定的Essay字数而发愁&#xff0c;毕竟既不能写得太少&#xff0c;又不能写得太多&#xff0c;所以很纠结。那么如何根据老师规定的字数进行删减呢&#xff1f…

Talk | 微软亚洲研究院宋恺涛南大余博涛:面向文本/音乐序列任务的Transformer注意力机制设计

本期为TechBeat人工智能社区第456期线上Talk&#xff01; 北京时间11月22日(周二)20:00&#xff0c;微软亚洲研究院研究员——宋恺涛与南京大学硕士研究生——余博涛的Talk将准时在TechBeat人工智能社区开播&#xff01; 他们与大家分享的主题是: “面向文本/音乐序列任务的Tra…

String类_Java(一)

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE领域博主 专栏&#xff1a;JavaSE &#x1f33c;作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 前言 一、构造字符串 二、Sring对象的比较 2.1 比较是否引用同一对象 2.2 比较…

跨平台编译工具--CMake上手教程

文章目录一、引入二、基本关键字1.PROJECT2.SET3.MESSAGE4.ADD_EXECUTABLE5.ADD_SUBDIRECTORY(1)使用(2)CMakeLists执行顺序(3)输出文件的位置6.INSTALL(1)安装文件(2)安装非目标文件可执行文件(3)安装目录(4)安装指令7.ADD_LIBRARY8.SET_TARGET_PROPERTIES三、语法的基本规则四…

知识引擎藏经阁天花板——高性能Java架构核心原理手册

开场 本书是按照程序设计与架构的顺序编写的&#xff0c;共13章。 第1章介绍学习高性能Java应了解的核心知识&#xff0c;为前置内容。 第2章和第3章讲解在编写代码之前&#xff0c;如何高效地为My SQL填充亿级数据&#xff0c;并对My SQL进行基准测试&#xff0c;以便在之后…

Linux-awk和printf

printf printf ‘输出类型输出格式’ 输内容 输出类型&#xff1a; %ns 输出字符串&#xff0c;n是数字指代输出几个字符 %ni 输出整数&#xff0c;n是数字&#xff0c;指代输出几个数字 %m.nf 输出浮点数&#xff0c;m和n是数字&#xff0c;指代输出总位数和小数位数&#xf…

YOLO V1学习总结

图片大小&#xff1a;448 * 448 —> 7 * 7 *&#xff08;5 * B C&#xff09; 5&#xff1a;每个框的x,y,w,h,confidence; B2&#xff1a;在7*7的feature上&#xff0c;每个cell会生成2个预测框&#xff1b; C&#xff1a;类别数。 损失函数 坐标中心误差和位置宽高的误差…

卷积神经网络基本概念

卷积神经网络基本概念1. 感受野2. 卷积核3. 特征图【feature map】4. 通道【channel】5. 填充【padding】6. 步长【stride】7. 池化【pooling】8. dropout数字1处&#xff1a;一个圈表示一个神经元数字2处&#xff1a;一个圈表示一个神经元&#xff0c;圈的大小表示感受野的大小…

基于matlab的最小支配集CDS仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 支配集的定义如下&#xff1a;给定无向图G &#xff08;V , E&#xff09;,其中V是点集&#xff0c; E是边集&#xff0c; 称V的一个子集S称为支配集当且仅当对于V-S中任何一个点v, 都有…

一、FFmpeg 的初尝试《FFmpeg 音视频开发基础入门到实战》

学习目标 了解 FFmpeg学习 FFmpeg 工具的下载及环境配置了解 FFmpeg 工具的使用方式了解 FFmpeg play 的使用方法了解 FFmpeg paly 的音量设置、窗口设置、音量设置等设置方法 一、了解 FFmpeg FFmpeg 是一个音视频处理的工具&#xff0c;通过 FFmpeg 可以对视频进行旋转、缩…

新零售SaaS架构:多租户系统架构设计

什么是多租户&#xff1f; 多租户是SaaS领域的特有产物&#xff0c;在SaaS服务中&#xff0c;租户是指使用SaaS系统的客户&#xff0c;租户不同于用户&#xff0c;例如&#xff0c;B端SaaS产品&#xff0c;用户可能是某个组织下的员工&#xff0c;但整个企业组织是SaaS系统的租…

得数据者得天下!作为后端开发必备技能之一的MySQL,这份十多年经验总结的应用实战与性能调优我想你肯定是需要的!

MySQL对于很多Linux从业者而言&#xff0c;是一个非常棘手的问题&#xff0c;多数情况都是因为对数据库出现问题的情况和处理思路不清晰。在进行MySQL的优化之前必须要了解的就是MySQL的查询过程&#xff0c;很多的查询优化工作实际上就是遵循一些原则让MySQL的优化器能够按照预…

跑步戴什么耳机比较好、精挑五款最佳跑步耳机推荐

运动蓝牙耳机近几年受到市场的欢迎&#xff0c;种类越来越多&#xff0c;各类功能也日益五花八门&#xff0c;消费者很难准确的进行分辨&#xff0c;一不小心可能买到华而不实的产品。现在了解一下值得入手的运动蓝牙耳机&#xff0c;从多个角度对蓝牙耳机进行评估后&#xff0…

大数据项目之电商数仓、实时数仓同步数据、离线数仓同步数据、用户行为数据同步、日志消费Flume配置实操、日志消费Flume测试、日志消费Flume启停脚本

文章目录8. 实时数仓同步数据9. 离线数仓同步数据9.1 用户行为数据同步9.1.1 数据通道9.1.1.1 用户行为数据通道9.1.2 日志消费Flume配置概述9.1.2.1 日志消费Flume关键配置9.1.3 日志消费Flume配置实操9.1.3.1 创建Flume配置文件9.1.3.2 配置文件内容如下9.1.3.2.1 配置优化9.…

Arcpy新增随机高程点、空间插值及批量制图

&#xff08;1&#xff09;在“地质调查点基础数据表.xls”中图幅范围内增加200个随机位置的高程点。构建一个shape文件&#xff0c;采用自定义工具的模式&#xff0c;参数有两个&#xff1a;一个是让用户选择excel文件&#xff0c;一个让用户指定新生成的文件名。 &#xff08…

五子棋小游戏——Java

文章目录一、内容简介&#xff1a;二、基本流程三、具体步骤1.菜单栏2.创建棋盘并初始化为空格(1)定义行数、列数为常量(2)定义棋盘(3)给棋盘添加坐标并初始化棋盘为空格3.打印棋盘4.玩家落子5.判断输赢四、代码实现五、效果展示一、内容简介&#xff1a; 五子棋小游戏是我们日…