浅谈 Mybatis 框架
文章目录
- 一、什么是MyBatis?
- 1.2、JDBC
- 二、使用Mybatis
- 2.1、配置MyBatis开发环境
- 2.1.1、配置连接字符串
- 2.1.2、配置MyBatis中的XML路径
- 2.2、使用MyBatis模式和语法操作数据库
- 三、使用 Mybatis 进行增删改查操作的要点
- 3.1、ResultMap的用法
- 四、Mybatis操作难点
- 4.1、#{ } 和 ${ } 的区别
- 4.1.1、SQL注入问题
- 4.2、like 模糊查询
- 4.3、多表查询、联合查询
- 4.3、动态 sql 的使用
- 4.3.1、if 标签
- 4.3.2、trim 标签
- 4.3.3、where 标签
- 4.3.4、set 标签
- 4.3.5、foreach 标签
一、什么是MyBatis?
MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程(多条SQL语句的集合)以及高级映射。MyBatis 去除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO (Plain Old Java Objects,普通老式Java对象)为数据库中的记录。
存储过程:

高级映射:程序中的类对应数据库中的表,程序中的类里的属性对应数据库的表中的字段。ORM把数据库映射为对象:数据库表(table) -->类(class)、
记录(record, 行数据) -->对象(object)、字段(field) -->对象的属性(attribute)
简单来说MyBatis是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库工具。
1.2、JDBC
我们之前使用JDBC连接数据库,那为什么还要学习MyBatis?这是因为JDBC操作十分繁琐。以下是JDBC的操作流程:
(1)、创建数据库连接池DataSource
(2)、通过DataSource获取数据库连接Connection
(3)、编写要执行带 ?占位符的SQL语句
(4)、通过Connection及SQL创建操作命令对象Statement
(5)、替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
(6)、使用Statement执行SQL语句
(7)、查询操作:返回结果集ResultSet,更新操作:返回更新的数量
(8)、处理结果集
(9)、释放资源
JDBC代码例子的链接
二、使用Mybatis

学会使用Mybatis需要掌握两个步骤:
2.1、配置MyBatis开发环境
在项目中添加MyBatis:

注意:框架 framework 和 框架 Driver 必须成对出现。

当项目中添加了数据库框架后,启动项目是失败的也不要慌张,这是正常现象。
因为项目中添加了数据库框架之后,却没有配置数据库的路径,所以项目启动报错。(一台机器上可以安装很多个数据库,想要连接哪个数据库就需要指定那个数据库的路径,才能够连接成功。)
2.1.1、配置连接字符串
那怎么指定呢??此时就需要配置连接字符串和MyBatis。需要进行两项设置,数据库连接字符串设置和MyBatis的XML文件配置。
(1)、配置连接字符串(4项)
如果是application.yml配置文件,则添加如下内容(系统配置项):(给的是模板,具体内容以自己的数据库为准)
#数据库连接配置
spring:datasource:url: jdbc :mysql://localhost:3306/mycnblogcharacterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

2.1.2、配置MyBatis中的XML路径
MyBatis中有两种实现数据库增删改查的方式,分别是:1、使用 XML 的范式。2、一种是使用注解的方式。
虽然使用注解的方式来写sql语句去实现数据库的增删改查功能一开始会比较容易,但是这是假象,只适合简单的sql语句以及简单的功能,但是当业务复杂起来的时候,使用注解的方式就十分不方便,同时使用注解的方式还容易将代码与sql语句混杂在一起,不容易实现代码的复用性、简洁性。因此我们通常会使用XML文件来实现数据库的增删改查。
只放个注解的例子图,不推荐使用这种方式,现在很少有人用了。

这是使用XML的方式:
因为Mybatis由2部分组成:
1、接口 ( interface ) :接口里会声明所有操作方法。这些方法是给程序里的其他类来调用。
2、使用 XML 实现接口。即XML里需要写具体的SQL语句。
想要使用 XML 的方式实现数据库的增删改查,还需要在配置文件中配置如下内容:(这些配置信息是告诉Mybatis要使用哪些文件)

#设置mybatis的xml保存路径
mybatis:mapper-locations: classpath:mapper/*Mapper.xml
2.2、使用MyBatis模式和语法操作数据库
这一步就是遵循MyBatis的写法在项目中构建相应的业务实现即可。
项目的业务交互图:

此处是一个项目例子来使用MyBatis模式和语法操作数据库:
一、基础准备
(1)、首先需要创建一个ssm的项目,项目需要准备好Mybatis Framework以及 MySQL Driver ,创建好后将配置文件中的配置信息先配置好:

(2)、然后在项目中依次创建好 controller层(控制器层)、service层(服务层)、mapper层(数据库持久层)、entity层(实体类)。
(3)、然后需要准备一个数据库,数据库中含有一张表,将表与程序中的类映射起来。


二、构建 Mapper 层的代码实现
(1)、在mapper层定义一个接口:
接口中可以含有多个方法,这些方法就对应你项目的增删改查或者其他的功能模块。

(2)、创建 XML 实现

在mapper包下创建一个 xml 文件:


三、实现服务层代码

四、实现控制器层代码

写完代码后,启动项目,在浏览器上输入URL,获取数据库中的数据:

三、使用 Mybatis 进行增删改查操作的要点
(1)、使用Mybatis进行查询操作

查询操作的两个必备属性中,第一个属性是id;第二个属性写法可以是 ResultType,也可以是 ResultMap。
使用ResultType,是因为程序中的实体类里的属性名称都和数据库中表的字段名称一致,所以可以使用ResultType。
使用ResultMap,是因为一般在公司,数据库是专门由DB负责的,而程序代码的书写由程序员负责,一般开始项目大家都是同时开工,程序员不知道DB设计出的数据库里面会用什么表名、字段名,因此此时想要让程序与表映射,需要用到ResultMap。(即ResultMap 用在当程序中的属性名与数据库表中的字段名不一致时)。
举个例子:

这是因为在查询的过程中,如果数据库表的字段名能够与程序中的属性名对应上,那就将数据库中的数据赋值给程序中的属性,如果数据库表中的字段名和程序中的属性名对应不上,那程序中的属性值就是null。
插入、删除、修改操作时也有这样的情况,但是和查询时相反的。若程序中的属性名与数据库表中的字段名匹配,可以赋值,操作成功,否则反之。
ResultMap(返回字典映射) 应用场景:
(1)、字段名称和程序中的属性名不同的情况,可使用resultMap配置映射;
(2)、一对一和一对多关系可以使用resultMap映射并查询数据。
3.1、ResultMap的用法
(1)、先声明

(2)、再使用

除了使用 resultMap 的方法,还有另一种更加简单的方法:
使用数据库别名 as 重命名。

(2)、使用Mybatis进行添加操作

因为我们的IDEA是默认隐藏Mybatis生成sql的执行细节,因此如果想要让控制台打印我们所执行的sql语句,可以在配置文件中进行配置。配置后,可利用sql语句排查问题。

配置文件:


(3)、使用Mybatis进行删除操作

(4)、使用Mybatis进行修改操作

Mybatis项目例子,这个链接是上面所写的项目例子与数据库所进行的增删改查的操作的具体代码,大家可以跟着动手写一写,熟能生巧。
四、Mybatis操作难点
前面在项目例子中演示的增删改查操作,是最基本最简单的操作,但其实在实际项目中,远比这些难得多,不仅仅涉及到对一个表的增删改查,还会涉及到多表查询操作、联合查询、条件查询…这个时候的sql语句就会比较难了。
4.1、#{ } 和 ${ } 的区别
在.xml文件里书写sql语句时,其实我们一般见到的都是 #{ } 类型的:

但是其实 ${ } 也可以实现和 #{ } 一样的功能,但是为什么现在常见的都是使用#{ },而 ${ }却很少见呢?他们有什么区别?
#{ } 的sql语句时使用的是预编译处理,即sql语句中先使用占位符?。这样的好处就是先占了才赋值,可以适配多种情况,不管是整型还是字符串…


而 ${ } 的sql语句是直接赋值,直接赋值的话整型的情况下没有问题,但是字符串的情况下就会有问题:




但是,${ } 有一个 #{ }不具备的重要功能:能够传递一些关键字。(但是在使用 ${ } 传递关键字时,我们还必须确定这个传递的值能够穷举:就是需要先在 controller 层对这个值进行参数校验,比如传的是一个order值,这个order变量它的取值是否是desc或者asc,如果都不是,不给传值,避免 ${ } 的sql注入问题)

代码实现:


单元测试:


4.1.1、SQL注入问题
我们上面说了,传关键字是 ${ } 的唯一应用场景(是因为 ${ } 不安全,会产生SQL注入的问题)。但是我们必须保证传的这个参数是可预期的,如果传的是一个不可预期的参数,有可能会产生SQL注入的问题:因为 ${ } 是直接赋值,因此一些有心人会抓住这个漏洞做一些非法的事情。
譬如:当我们进行登陆操作时,当使用 ${ } 进行登陆操作的sql语句书写时(要想测试sql注入现象成功,需要保证数据库里只有一行记录的情况下才可以):

单元测试1:

单元测试2(sql注入问题):

但是使用 #{ } 就没有sql注入这样的问题:


那么为什么这样一串字符串:’ or 1='1 就会引起sql注入问题?

总结:#{ } 和 ${ } 的区别:
(1)、 ${ } 存在 sql注入问题,而 #{ } 不存在。
(2)、 ${ } 是直接赋值,而#{ } 是采用预编译的。
使用 ${ } 的注意事项:
(1)、确保传入的值是可穷举,可预期的。
(2)、需要先在 controller 层进行参数校验。
4.2、like 模糊查询



此时可以采用 mysql 的内置函数 concat() 进行拼接:


4.3、多表查询、联合查询
多表查询是非常容易遇到的操作,并且多表查询比单表查询要难。当我们需要进行多表查询,但是实体类却只包含单表查询的实体类,该怎么办??



针对上面的问题,有两个解决方法:
(1)、不再继承基础类,直接写全所有属性:


(2)、仍旧是继承自基础类,但是需要将lombok生成的toString()覆盖

因此我们可以在扩展类中自己写一个 toString() 方法,将lombok自动生成的toString() 方法覆盖掉:

注意:一般我们在写实体类的时候,习惯将类都实现 Serializable 接口并新增一个版本字段。因为我们写的实体类,不可避免后面都会有可能进行序列化/反序列化。
当我们遇到多表联查,直接采用这个解决方案即可:
联表查询语句(left jion / inner join)+XXXVO 解决。
4.3、动态 sql 的使用
动态 sql 是 Mybatis 强大特性之一,能够实现复杂条件下不同的 sql 拼接。
动态sql的应用场景一般在当前界面既含有必填项又含有非必填项,如下图此类:

4.3.1、if 标签
if标签是一个条件判断,如果if标签里的属性test是true,就执行if标签里的内容,如果属性test是false,就不执行if标签里的内容。if标签一般用于含有较少非必填项的场景。
if标签语法:
<if test = "参数名 != null and 参数名 != ''">...
</if>
例子:

使用动态sql时:


4.3.2、trim 标签
trim标签一般用于含有多个非必填项的场景。trim要求里边必须至少包含一个if标签去配合使用!
trim标签的语法:

这两标签一般用于插入操作。
4.3.3、where 标签
where 标签的语法:


4.3.4、set 标签
set 标签语法:

以上标签也可以使用 < trim prefix= “set” suffixoverrides=“,”> < /trim>替换。
单元测试成功:

4.3.5、foreach 标签
foreach标签的应用场景一般是在批量操作上。例如批量删除批量修改批量添加…当系统进行批量操作时,前端传的是一个集合,后端需要对集合进行遍历时就可以使用该标签。
< foreach> 标签有如下属性:
(1)、collection: 绑定方法参数中的集合,如List, Set, Map或数组对象
(2)、item: 遍历时的每一 个对象
(3)、open:语句块开头的字符串
(4)、close: 语句块结束的字符串
(5)、separator:每次遍历之间间隔的字符串
foreach标签语法:



相关文章:
浅谈 Mybatis 框架
文章目录 一、什么是MyBatis?1.2、JDBC 二、使用Mybatis2.1、配置MyBatis开发环境2.1.1、配置连接字符串2.1.2、配置MyBatis中的XML路径 2.2、使用MyBatis模式和语法操作数据库 三、使用 Mybatis 进行增删改查操作的要点3.1、ResultMap的用法 四、Mybatis操作难点4.1、#{ } 和…...
【星海随笔】OSPF协议
OSPF OSPF 可在单一自治系统(Autonomous System, AS)内决策路由。OSPF 是目前内部网关协议中使用最为广泛、性能最优的一个动态路由协议。 (1) OSPF 的特点。可适应大规模的网,路由变化收敛速度块,无路由自环,支持变…...
Vue 使用elementUI-plus el-calendar加 公历转农历 是否节假日 等
效果图: 1. 使用到自定文件 calendar.js /*** 1900-2100区间内的公历、农历互转* charset UTF-8* Author Jea杨(JJonlineJJonline.Cn)* Time 2014-7-21* Time 2016-8-13 Fixed 2033hex、Attribution Annals* Time 2016-9-25 Fixed lunar LeapMonth Param…...
SQL-锁
一.锁的介绍 锁是计算机协调多个进程或线程并发访问一资源的机制。在数据中,除传统的计算资源(CPU,RAM,I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因…...
索引小tips
一、优化原则 关于创建索引: 1. 【强制】InnoDB表必须主键为id int/bigint auto_increment,且主键值禁⽌被更新 。 2. 【强制】InnoDB和MyISAM存储引擎表,索引类型必须为 BTREE 。 3. 【建议】主键的名称以 pk 开头,唯⼀键以…...
2024年【中级消防设施操作员(考前冲刺)】报名考试及中级消防设施操作员(考前冲刺)免费试题
题库来源:安全生产模拟考试一点通公众号小程序 中级消防设施操作员(考前冲刺)报名考试是安全生产模拟考试一点通生成的,中级消防设施操作员(考前冲刺)证模拟考试题库是根据中级消防设施操作员(…...
数据结构:栈(含源码)
目录 一、栈的概念和结构 二、栈的实现 2.1 头文件 2.2 各个功能的实现 初始化栈 入栈 出栈 获取栈顶元素和栈中有效个数 判断栈是否为空 栈的销毁 2.3 测试 完整源码 一、栈的概念和结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和…...
如何使用Markdown编辑器
欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…...
当代最火的哲学家颜廷利:全球公认十个最厉害的思想家之一
颜廷利书法特点和艺术成就:全球公认十个最厉害的思想家之一,颜廷利教授是一位杰出的书法家,他的书法作品不仅体现了中国传统文化,而且在国内外享有高度评价,对当代书法艺术产生了深远的影响。在中国十大顶级哲学家排行榜上,当今世界最重要的思想家颜廷利教授的书…...
android13内核增加调试接口给上层使用
总纲 android13 rom 开发总纲说明 目录 1.前言 2.处理方法分析 3.代码参考 3.1方法1 3.2方法2 3.3方法3 3.4方法4 4.彩蛋 1.前言 有时候,我们在开机的过程中,adb服务还没有起来,系统奔溃了,不能正常开机,我们没法看到相关的logcat信息,导致我们不能很快的定…...
linux:phpstudy安装及日常命令使用[表格]
官网安装:小皮面板下载安装,一键管理服务器-小皮面板 (xp.cn) centos安装: yum install -y wget && sudo wget -O install.sh https://dl.xp.cn/dl/xp/install.sh && sudo bash install.sh 快速使用 [rootlocalhost ~]# …...
【python】Linux升级版本
目的 迁移项目包路径到服务器上 查看服务器包是否和本地已有项目python版本相同然后发现~嗯不一样 项目上包时用的3.8~ 服务器用的2.7 查看方法: python -version解决方案 一:项目所有包重新下载 二:升级服务器python版本 第二种步骤&…...
鸿蒙开发if判断有点坑
它的判断和Android的有点不同,归结到底不是同一种语言,数据类型不一样 if (0) {logContent("aa","0") } else {logContent("aa","00")...
IT课程学习搭子
各种IT课程齐全可学,价格你绝对想不到,相比于培训班有以下优势: 1、避免被割韭菜,避免踩坑,避免交智商税,最低的成本学最有价值的课,同时又能达到比培训班更好的效果 2、收徒,带你学…...
hive拼接字符串concat函数的用法
在 Hive 中,字符串拼接是一种常见的操作,用于将多个字符串连接在一起形成一个新的字符串。这在数据处理和分析过程中经常会用到,比如将不同列的值拼接成一个完整的信息、拼接成文件路径等等。 字符串拼接函数 在 Hive 中,我们可…...
Linux-理解shell
文章目录 5. 理解shell5.1 shell的类型5.2 交互shell和系统默认shell5.3 安装zsh shell程序5.4 shell的父子关系5.5 命令列表5.6 命令分组5.7 使用命令分组创建子shell5.8 子shell用法5.9 shell的非内建命令和内建命令5.9.1 非内建命令5.9.2 内建命令5.9.3 history和alias命令介…...
FutureTask详解
目录 FutureTask详解1、FutureTask简介2、FutureTask内部结构继承结构类属性构造方法内部类WaitNode 3、Runnable、Callable、Future、RunnableFuture接口①、Runnable接口②、Callable接口③、Future接口④、RunnableFuture接口总结对比 4、FutureTask的使用示例普通Thread使用…...
javase综合案例4 -- 考试系统
文章目录 一,项目要求二,创建实体类ExamItem三,创建考试服务类ExamService3.1 全局变量 考题列表itemList(List< ExamItem >类型),答案数组answerArr (String[]类型),得分score3.2 初始化方法init()3.3 打印菜单…...
Logistic回归
Logistic回归模型: 适用于二分类或多分类问题,样本特征是数值型(否则需要转换为数值型) 策略:极大似然估计 算法:随机梯度 或 BFGS算法(改进的拟牛顿法) 线性回归表达式…...
Langchain-Chatchat+Xinference集成部署
Langchain-ChatchatXinference集成部署 安装环境: 系统:Anolis OS 8.9 python版本:Python 3.9.19 Langchain-Chatchat版本:0.3.1.3 Xinference版本:v0.13.3 模型选择(下载时需要科学上网)&#…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
