Mybatis 01

JDBC回顾

select 语句 "select *from student" 演示:

         驱动包

JDBC 的操作流程:

1.  创建数据库连接池 DataSource
2. 通过 DataSource 获取数据库连接 Connection
3. 编写要执⾏带 ? 占位符的 SQL 语句
4. 通过 Connection 及 SQL 创建操作命令对象 Statement
5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
6. 使⽤ Statement 执⾏ SQL 语句
7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
8. 处理结果集
9. 释放资源

Mybatis 是什么

MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC的开发
持久层:指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的

简单来说 MyBatis 是更简单完成程序和数据库交互的框架,是更简单的操作和读取数据库⼯具 

Mybatis 入门

Mybatis操作数据库的步骤:
1. 准备⼯作(创建springboot⼯程、数据库表准备、实体类)
2. 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)
3. 编写SQL语句(注解/XML)
4. 测试

准备工作

创建springboot⼯程,并导⼊ mybatis 的依赖、mysql 的驱动包

    Lombok                Spring Web                Mybatis Framework                 MySQL Driver

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加 MySQL 驱动
项⽬⼯程创建完成后,⾃动在pom.xml⽂件中,导⼊Mybatis依赖和MySQL驱动依赖
版本会随着SpringBoot 版本发⽣变化, ⽆需关注

创建用户表 mybatis_test  

创建对应的实体类 UserInfo

实体类的属性名与表中的字段名⼀⼀对应

配置数据库连接字符串

Mybatis中要连接数据库,需要数据库相关参数配置
MySQL驱动类
登录名
密码
数据库连接字符串

如果使⽤ MySQL 是 5.x 之前的使⽤的是"com.mysql.jdbc.Driver",如果是⼤于 5.x 使⽤的
是“com.mysql.cj.jdbc.Driver

写持久层代码

在项⽬中, 创建持久层接⼝ UserInfoMapper

Mybatis的持久层接⼝规范⼀般都叫 XxxMapper
@Mapper注解:表⽰是MyBatis中的Mapper接⼝
程序运⾏时, 框架会⾃动⽣成接⼝的实现类对象(代理对象),并给交Spring的IOC容器管理
@Select注解:代表的就是select查询,也就是注解对应⽅法的具体实现内容

单元测试

在创建出来的SpringBoot⼯程中,在src下的test⽬录下,已经⾃动帮我们创建好了测试类 ,我们可以 直接使⽤这个测试类来进⾏测试
测试类上添加注解 @SpringBootTest,该测试类在运⾏时,就会⾃动加载Spring的运⾏环境
通过@Autowired这个注解, 注⼊要测试的类, 就可以开始进⾏测试了
使⽤ Idea ⾃动⽣成测试类
除此之外, 也可以使⽤Idea⾃动⽣成测试类 :
1)在需要测试的Mapper接⼝中, 右键 -> Generate -> Test
2)选择要测试的⽅法, 点击 OK

使用 IDEA 自动生成测试类进行单元测试

返回结果中, 可以看到, 只有SQL语句中查询的列对应的属性才有赋值

MyBatis的基础操作

打印日志

在Mybatis当中我们可以借助⽇志, 查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果
在配置⽂件中进⾏配置即可
mybatis:
  configuration: # 配置打印 MyBatis⽇志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

重启程序,查看输出结果

参数传递

SQL语句中的id值一般不能写成固定数值,需要变为动态的数值——>
在⽅法中添加⼀个参数(id),将⽅法中的参数,传给SQL语句
使⽤   #{}   的⽅式获取⽅法中的参数
@Select("select id,username,password,age,gender from userinfo where id = #{id}")
UserInfo getUser(Integer id);

@Test
void getUserInfoAll() {
    UserInfo userInfo = userInfoMapper.getUser(1);
    System.out.println(userInfo);
}

如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{…} ⾥⾯的属性名可以随便写,如:#{id}、#{value}。建议和参数名保持⼀致
@Select("select id,username,password,age,gender from userinfo where id = #{userId}")
UserInfo getUser(@Param("userId") Integer id);
可以通过 @Param  设置参数的别名, 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和@Param 设置的⼀样 
@Select("select id,username,password,age,gender from userinfo where id = #{id} and password = #{password}")
UserInfo getUser(Integer id,String password);

@Test
void getUserInfoAll() {
    UserInfo userInfo = userInfoMapper.getUser(1,"admin");
    System.out.println(userInfo);
}

如果只有一个结果返回,可以使用对象或者集合接受

如果有多个结果返回,必须使用集合接受

程序会根据参数自动生成一些参数,例如 param1 对应方法的第一个参数...

​​​​​​​Mybatis开发方式 

Mybatis的开发有两种⽅式:
1. 注解
2. XML
使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中

注解

增(Insert)

如果设置了 @Param 属性, #{...} 需要使⽤ 参数.属性 来获取
@Insert("insert into userinfo (id,username,password,age,gender)" +
        " values(#{info.id},#{info.username},#{info.password},#{info.age},#{info.gender})")
Integer InsertUserInfo(@Param("info") UserInfo userInfo); 

返回主键 

Insert 语句默认返回的是 受影响的⾏数
但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id
如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解
设置 useGeneratedKeys=true 之后, ⽅法返回值依然是受影响的⾏数, ⾃增 id 会设置在上
keyProperty 指定的属性中
useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字段),默认值:false.
•  keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)

删(Delete)

改(Update)

查(Select)

们在上⾯查询时发现, 有⼏个字段是没有赋值的, 只有Java对象属性和数据库字段⼀模⼀样时, 才会进⾏赋值
从运⾏结果上可以看到, 我们SQL语句中, 查询了delete_flag, create_time, update_time, 但是这⼏个属性却没有赋值
MyBatis 会根据⽅法的返回结果进⾏赋值.
1)⽅法⽤对象 UserInfo接收返回结果, MySQL 查询出来数据为⼀条, 就会⾃动赋值给对象.
2)⽅法⽤List<UserInfo>接收返回结果, MySQL 查询出来数据为⼀条或多条时, 也会⾃动赋          值给List
3)但如果MySQL 查询返回多条, 但是⽅法使⽤UserInfo接收, MyBatis执⾏就会报错
原因分析:
当⾃动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性

 解决方法:1)起别名  2)结果映射  3)驼峰命名

1)起别名

在SQL语句中,给列名起别名,保持别名和实体类属性名⼀样

 2)结果映射

如果其他SQL, 也希望可以复⽤这个映射关系, 可以给这个Results定义⼀个名称
使⽤ id 属性给该 Results 定义别名, 使⽤ @ResultMap 注解来复⽤其他定义的 ResultMap

 3)驼峰命名

通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), ⽽ Java 属性⼀般遵循驼峰命名法约定
为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为
true

MyBatis XML 配置文件

MyBatis XML的⽅式需要以下两步:

1. 配置数据库连接字符串和MyBatis
2. 写持久层代码

配置连接字符串和MyBatis

此步骤需要进⾏两项设置,数据库连接字符串设置和 MyBatis 的 XML ⽂件配置

持久层代码的编写准备

添加 mapper 接⼝
数据持久层的接⼝定义:    UserInfoXmlMapper.java

 添加 UserInfoXMLMapper.xml

数据持久成的实现,MyBatis 的固定 xml 格式:
创建UserInfoXMLMapper.xml, 路径参考yml中的配置
以下是对以上标签的说明:
<mapper> 标签:需要指定 namespace 属性,表⽰命名空间,值为 mapper 接⼝的 全限定
,包括全包名.类名
<select> 查询标签:是⽤来执⾏数据库的查询操作的:
id :是和 Interface(接⼝)中定义的⽅法名称⼀样的,表⽰对接⼝的具体实现⽅法
resultType :是返回的数据类型,也就是开头我们定义的实体类

增(Insert)

       .java

                                     .xml

1)如果使⽤@Param设置参数名称的话, 使⽤⽅法和注解类似 

2)返回⾃增 id,接⼝定义不变, Mapper.xml 实现设置useGeneratedKeys 和keyProperty属性

删(Delete)

改(Update)

查(Select)

同样的, 使⽤XML 的⽅式进⾏查询, 也存在数据封装的问题
解决办法和注解类似:
1. 起别名
2. 结果映射
3. 驼峰命名
其中1,3的解决办法和注解⼀样,不再多说, 接下来看下xml如果来写结果映射

增,删,改返回的是影响的行数

查 返回的结果可能是字符串,对象,数字...需要指定类型

 

从控制台返回的结果可知,此时仍未查到要求的值

 

其他查询操作

多表查询

Mybatis 不分单表还是多表, 主要就是三部分: SQL, 映射关系和实体类

通过映射关系, 把SQL运⾏结果和实体类关联起来

如果名称不⼀致的, 采⽤ResultMap, 或者别名的⽅式解决, 和单表查询⼀样

在配置文件中指定的库中创建 作者类 

#{} 和 ${}

#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句中. #{} 会根据参数类型, ⾃动拼接引号 '' 
${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 '' 
参数为数字类型时, 也可以加上, 查询结果不变, 但是可能会导致索引失效, 性能下降
#{} 和 ${}区别:
#{} 和 ${} 的区别就是预编译SQL和即时SQL 的区别
1. 性能更⾼
绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同(⽐如 select 的 where ⼦句值不同, update 的 set ⼦句值不同, insert 的 values 值不同). 如果每次都需要经过上⾯的语法解析, SQL优化、SQL编译等,则效率就明显不⾏了
预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译(只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率
2. 更安全(防⽌SQL注⼊)
SQL注⼊:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的⽅法
由于没有对⽤⼾输⼊进⾏充分检查,⽽SQL⼜是拼接⽽成,在⽤⼾输⼊参数时,在参数中添加⼀些SQL关键字,达到改变SQL运⾏结果的⽬的,也可以完成恶意攻击

SQL注入演示:

正常输入——>

SQL注入场景——>

排序功能

${} 会有SQL注⼊的⻛险, 所以我们尽量使⽤#{}完成查询

然而 ${}存在,就一定有其应用的场景:

使⽤ ${sort} 可以实现排序查询, ⽽使⽤ #{sort} 就不能实现排序查询了
注意: 此处 sort 参数为String类型, 但是SQL语句中, 排序规则是不需要加引号 '' 的, 所以此时的${sort} 也不加引号
当使⽤ #{sort} 查询时, asc 前后⾃动给加了引号, 导致 sql 错误
#{} 会根据参数类型判断是否拼接引号 ''
如果参数类型为String, 就会加上 引号
表名作为参数时, 也只能使⽤ ${}

like 查询

like 使⽤ #{} 报错:

把 #{} 改成 ${} 可以正确查出来, 但是${}存在SQL注⼊的问题, 所以不能直接使⽤ ${}
解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:

数据库连接池

在上⾯Mybatis的讲解中, 使⽤了数据库连接池技术, 避免频繁的创建连接, 销毁连接
下⾯来了解下数据库连接池

介绍

数据库连接池负责分配、管理和释放数据库连接,它允许应⽤程序重复使⽤⼀个现有的数据库连接,⽽不是再重新建⽴⼀个
1)没有使⽤数据库连接池的情况: 每次执⾏SQL语句, 要先创建⼀个新的连接对象, 然后执⾏        SQL语句, SQL语句执⾏完, 再关闭连接对象释放资源. 这种重复的创建连接, 销毁连接⽐        较消耗资源
2)使⽤数据库连接池的情况: 程序启动时, 会在数据库连接池中创建⼀定数量的Connection          对象, 当客⼾请求数据库连接池, 会从数据库连接池中获取Connection对象, 然后执⾏            SQL, SQL语句执⾏完, 再把Connection归还给连接池

使用

常⻅的数据库连接池:
C3P0
DBCP
Druid
Hikari
⽬前⽐较流⾏的是 Hikari, Druid
1. Hikari : SpringBoot默认使⽤的数据库连接池
2. Druid
如果我们想把默认的数据库连接池切换为Druid数据库连接池, 只需要引⼊相关依赖即可
< dependency >
      < groupId >com.alibaba</ groupId >
      < artifactId >druid-spring-boot-starter</ artifactId >
      < version >1.1.17</ version >
</ dependency >

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基础数据结构--二叉树

一、二叉树的定义 二叉树是 n( n > 0 ) 个结点组成的有限集合&#xff0c;这个集合要么是空集&#xff08;当 n 等于 0 时&#xff09;&#xff0c;要么是由一个根结点和两棵互不相交的二叉树组成。其中这两棵互不相交的二叉树被称为根结点的左子树和右子树。 如图所示&am…

协议幻变者:DeviceNet转ModbusTCP网关开启机器手臂智能新纪元

技术背景DeviceNet是一种广泛应用于工业自动化领域的现场总线标准&#xff0c;它能够实现控制器与现场设备之间的高效通信&#xff0c;常用于连接各种传感器、执行器以及其他工业设备&#xff0c;如机器人、电机驱动器等&#xff0c;具有实时性强、可靠性高的特点。而ModbusTCP…

Spring Security 3.0.2.3版本

“前言” 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往复以至无…

MiFlash 线刷工具下载合集

MiFlash 线刷工具下载合集 MiFlash 线刷工具下载合集 – MIUI历史版本相较于小米助手的刷机功能&#xff0c;线刷还是偏好使用 MiFlash。特点是界面简单纯粹&#xff0c;有自定义高级选项&#xff0c;可以选择刷机不上 BL 锁&#xff0c;自定义刷机脚本&#xff0c;EDL 刷机模…

Oracle 多租户架构简介

目录 零. 简介一. CDB&#xff08;Container Database&#xff0c;容器数据库&#xff09;二. PDB&#xff08;Pluggable Database&#xff0c;可插拔数据库&#xff09;三. CDB 与 PDB 的比较四. 用户的种类五. XE 与 XEPDB1 零. 简介 ⏹Oracle 多租户架构&#xff08;Multit…

掌握大数据处理利器:Flink 知识点全面总结【上】

1.Flink的特点 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行状态计算。 Flink主要特点如下&#xff1a; 高吞吐和低延迟。每秒处理数百万个事件&#xff0c;毫秒级延迟。结果的准确性。Flink提供了事件时间(event--time)和处理时间(proces…

[论文阅读] (34)ESWA2024 基于SGDC的轻量级入侵检测系统

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代

Milvus Cloud BM25:重塑全文检索的未来 在最新的Milvus Cloud 2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了Milvus Cloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据…

常用的数据库类型都有哪些

在Java开发和信息系统架构中&#xff0c;数据库扮演着存储和管理数据的关键角色。数据库种类繁多&#xff0c;各有特色&#xff0c;适用于不同的应用场景。 1. 关系型数据库&#xff08;RDBMS&#xff09;&#xff1a; • 关系型数据库是最为人熟知的数据库类型&#xff0c;数据…

计算机网络—————考研复试

第一章、计算机网络体系结构 1. OSI参考模型和TCP/IP模型&#xff1a; OSI与TCP/IP的记忆方法&#xff1a;只需把OSI的七层记住&#xff0c;将应用层、表示层、会话层一起记&#xff0c;到TCP/IP变成应用层。物理层和数据链路层换成网络接口层。把网络层换个字变成网际层。 而…

从2024看2025前端发展趋势

前言 又至年关&#xff0c;回顾整个2024年&#xff0c;前端行业仍旧百废待兴&#xff0c;IT业界同样也未见有所起色&#xff0c;AI风潮也从狂热兴奋逐步走向了冷静稳定阶段&#xff0c;造成此形势感观并非单一行业或者某一企业之特例&#xff0c;实为政经等综合影响之结果。因…

国内机器视觉产业链全解析

欢迎关注《光场视觉》 简单的&#xff0c;我们可以把机器视觉产业链可以分为底层开发商&#xff08;核心零部件和软件提供商&#xff09;、集成和软件服务商&#xff08;二次开发&#xff09;&#xff0c;核心零部件及软件又可以再细分为光源、镜头、工业相机、图像采集卡、图…

node.js之---事件循环机制

事件循环机制 Node.js 事件循环机制&#xff08;Event Loop&#xff09;是其核心特性之一&#xff0c;它使得 Node.js 能够高效地处理大量并发的 I/O 操作。Node.js 基于 非阻塞 I/O&#xff0c;使用事件驱动的模型来实现异步编程。事件循环是 Node.js 实现异步编程的基础&…

如何在没有 iCloud 的情况下将数据从 iPhone 传输到 iPhone

概括 您可能会遇到将数据从 iPhone 转移到 iPhone 的情况&#xff0c;尤其是当您获得新的 iPhone 15/14 时&#xff0c;您会很兴奋并希望将数据转移到它。 使用iCloud最终可以做到这一点&#xff0c;但它的缺点也不容忽视&#xff0c;阻碍了你选择它。例如&#xff0c;您需要…

HTML——26.像素单位

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>像素</title></head><body><!--像素&#xff1a;1.指设备屏幕上的一个点&#xff0c;单位px&#xff0c;如led屏上的小灯朱2.当屏幕分辨率固定时&…

智能商业分析 Quick BI

Quick BI 是阿里云提供的一款智能商业分析&#xff08;BI&#xff09;工具&#xff0c;旨在帮助企业快速获取业务洞察、优化决策过程、提升数据分析效率。通过强大的数据可视化和分析功能&#xff0c;Quick BI 能够帮助用户轻松连接多种数据源、创建多维度的报表和仪表盘&#…

multisim仿真搭建三极管开关电路,低电平(5V)控制高电平(12V)输出

通过三极管搭建电路&#xff0c;低电平&#xff08;5V&#xff09;控制高电平&#xff08;12V&#xff09;输出 低电平输入&#xff1a;当输入信号为低电平时&#xff08;0V&#xff09;&#xff0c;三极管Q1处于截止状态。上拉电阻R1的存在&#xff0c;Q2输入端被拉到低电平&a…

Python跨年烟花

目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…

LeetCode - 初级算法 数组(删除排序数组中的重复项)

免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 删除排序数组中的重复项 这篇文章讨论如何从一个非严格递增的数组 nums 中删除重复的元素,使每个元素只出现一次,并返回新数组的长度。因为数组是排序的,只要是相同的肯定是挨着的,所以我们需要遍历所有数组,然…

【yolov5】实现FPS游戏人物检测,并定位到矩形框上中部分,实现自瞄

介绍 本人机器学习小白&#xff0c;通过语言大模型百度进行搜索&#xff0c;磕磕绊绊的实现了初步效果&#xff0c;能有一些锁头效果&#xff0c;但识别速度不是非常快&#xff0c;且没有做敌友区分&#xff0c;效果不是非常的理想&#xff0c;但在4399小游戏中爽一下还是可以…