[Spring] MyBatis操作数据库(进阶)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- 1. 数据库连接池
- 1.1 为什么会有连接池
- 1.2 常用的数据库连接池
- 2. 动态SQL
- 2.1 ``<if>``标签
- 2.2 ``<trim>``标签
- 2.3 ``<where>``标签
- 2.4 ``<set>``标签
- 2.5 ``<for each>``标签
- 2.6 ``<include>``标签
- 3. 案例练习(表白墙)
- 3.1 配置文件
- 3.2 Mapper层代码
- 3.3 Service层代码
- 3.4 Controller层代码
1. 数据库连接池
1.1 为什么会有连接池
数据库连接池技术也是一种池化技术,他与线程池类似,在通过Spring连接数据库的时候,避免了频繁的创建和销毁与数据库的连接.保证了资源的合理利用.
没有使用数据库连接池的情况: 在每一次在Spring中执行SQL语句的时候,都会先创建一个与数据库的连接对象,在执行完SQL语句之后,再关闭SQL语句,这种重复创建和销毁对象的行为比较浪费系统资源.
使用数据连接池的情况: 在程序启动的时候,会在连接池中创建Collection对象,在执行SQL语句的时候,会在连接池中申请一个连接对象,在执行SQL语句之后,又会把线程归还给连接池.
1.2 常用的数据库连接池
• C3P0
• DBCP
• Druid
• Hikari
目前比较流行的是Hikari,Druid,其中,Druid是阿里巴巴开源项目中的连接池.
其中Hikari是一个Spring程序中默认使用的连接池.如果想把连接池切换为Druid,我们需要在pom文件中引入依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version>
</dependency>
2. 动态SQL
动态SQL可以完成不同场景下的SQL拼接.
2.1 <if>标签

在我们注册用户的时候,我们有一个这样的问题,有时候有的选项不是必填项.在添加用户的时候SQL字段个数是不确定的.这时候就需要我们使用<if>标签了.比如gender性别是非必填字段:
接口定义:
public Integer insertUser2(UserInfo userInfo);
sql:
<insert id="insertUser2">insert into userinfo (id,username,password,age,<if test="gender != null">gender,</if>phone) values (#{id},#{username},#{password},#{age},<if test="gender != null">#{gender},</if>#{phone})
</insert>
或者我们也可以使用注解的方式,使用<script></script>标签把上面的xml语句括起来即可.但是我们不推荐用这种做法.
@Insert("<script>" +"INSERT INTO userinfo (username,`password`,age," +"<if test='gender!=null'>gender,</if>" +"phone)" +"VALUES(#{username},#{age}," +"<if test='gender!=null'>#{gender},</if>" +"#{phone})"+"</script>")
public Integer insertUser2(UserInfo userInfo);
注意if中的gender是对象的属性,不是SQL的字段,因为对象是从前端传过来的,我们在判断的时候,是判断前端有没有传值过来,而前段的值就是传到后端的方法参数中的.
2.2 <trim>标签
上面只使用if标签有一定的问题.要是我们在拼接SQL语句的时候,if标签在最后一个字段,比如:
<insert id="insertUser2">insert into userinfo (id,username,password,age,gender,<if test="phone != null">phone</if>) values (#{id},#{username},#{password},#{age},#{gender},<if test="phone != null">#{phone}</if>)
</insert>
当我们没有phone属性的时候,我们在gender字段后面就会多上一个逗号,这显然不符合sql的语法,所以我们就需要使用<trim>标签.
标签中有如下属性:
• prefix:表示整个语句块,以prefix的值作为前缀
• suffix:表示整个语句块,以suffix的值作为后缀
• prefixOverrides:表示整个语句块要去除掉的前缀
• suffixOverrides:表示整个语句块要去除掉的后缀
调整上面的插入语句:
<insert id="insertUser3">insert into userinfo<trim prefix="(" suffix=")" suffixOverrides="," prefixOverrides=",">id,username,password,age,gender,<if test="phone != null">phone</if></trim>values<trim prefix="(" prefixOverrides="," suffix=")" suffixOverrides=",">#{id},#{username},#{password},#{age},#{gender},<if test="phone != null">#{phone}</if></trim>
</insert>
假如所有的字段都是可选字段:
<insert id="insertUser4">insert into userinfo<trim prefixOverrides="," suffixOverrides="," suffix=")" prefix="("><if test="id != null">id,</if><if test="username != null">username,</if><if test="password != null">password,</if><if test="age != null">age,</if><if test="phone != null">phone</if></trim>values<trim prefix="(" suffix=")" suffixOverrides="," prefixOverrides=","><if test="id != null">#{id},</if><if test="username != null">#{username},</if><if test="password != null">#{password},</if><if test="age != null">#{age},</if><if test="gender != null">#{gender},</if><if test="phone != null">#{phone}</if></trim>
</insert>
trim标签中的参数的用意就是:在前面和后面只要有逗号,就都会去掉,之后再在sql语句中的前后拼接上括号.
这个标签就是把<trim>中的内容当做一个字符串,对这个字符串进行整体加减前后缀.
在注解中写的方法和上面的if标签是一样的,这里不再赘述.
2.3 <where>标签
下面这个场景,系统会根据我们的筛选条件,动态组装where条件.

这样的场景该如何实现呢?下面我们来看例子.
传入的用户对象,根据属性做where条件查询,用户对象中属性不为null的,都为查询条件.
接口定义:
public List<UserInfo> selectUser1(UserInfo userInfo);
根据传过来的对象限制查询条件.
sql:
<select id="selectUser1" resultType="com.jrj.mybatis.UserInfo">select * from userinfo<where><if test="gender != null">#{gender},</if><if test="age != null">#{age},</if><if test="deleteFlag != null">#{deleteFlag}</if></where>
</select>
<where>标签和<trim>标签类似,where可以去除掉前后的and和or,如果where后面没有字段的话,就没有where语句了,where关键字不予保留.效果和<trim prefix="where" prefixOverrides="and"> 相同,但是使用这个标签的时候,当没有限制条件的时候,where关键字就会保留下来.
2.4 <set>标签
根据传入的用户对象属性来更新用户数据,可以使用标签来指定动态内容.
方法接口:
public Integer updateUser1(UserInfo userInfo);
sql:
<update id="updateUser1">update userinfo<set><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if><if test="gender != null">gender = #{gender}</if></set> where id = #{id}
</update>
<set>标签和上面的<where>标签一样,会自动去除逗号,也会根据是否有更新字段来判断是否要添加set关键字.与<trim prefix="set" suffixOverrides=",">效果一样,但是在没有传入跟新字段的时候,不会去掉set关键字.
2.5 <for each>标签
对集合进行遍历的时候,可以用这个标签,一般与sql语句中的in配合使用.
对集合进行遍历时可以使用该标签。标签有如下属性:
• collection:绑定方法参数中的集合,如List,Set,Map或数组对象
• item:遍历时的每⼀个对象
• open:语句块开头的字符串
• close:语句块结束的字符串
• separator:每次遍历之间间隔的字符串
比如根据多个用户id删除用户数据.
接口:
public Integer updateDeleteFlag1(List<UserInfo> userList);
sql:
<update id="updateDeleteFlag1">update userinfo set delet_flagwhere id in<foreach collection="userList" item="id" open="(" close=")">#{id}</foreach>
</update>
这里我们在删除用户数据的时候,使用的是逻辑删除的方式:
删除方式一共有两种,一种是逻辑删除,一种是物理删除,物理删除就是使用Delete语句,在计算机的存储空间中彻底删除,想要回复只能通过日志回滚的方式进行恢复,非常麻烦.而逻辑删除就是把表中每个数据的必备字段,delete_flag标记为无效的数值,并没有从硬盘上真正删除掉,恢复的时候只需要把这个数值改成有效数值即可.我们在企业开发的时候,一般用的都是逻辑删除.
[补充] 其中的collection参数也可以用list1,list2来表示,和前面的方法形参与sql语句传参类似.
2.6 <include>标签
这个标签通常与<sql>标签配合使用,在xml文件中,有一些sql语句是赘余的,即sql语句中的赘余片段.

我们可以对重复的代码片段段进行抽取,将其通过 <sql> 标签封装到⼀个SQL片段.之后在每一个sql语句中使用<include>标签进行引用即可.
<sql>: 对可以重复引用的sql语句进行定义,在参数id中定义该sql片段的名字.<include>: 通过属性refid,指定引用的sql片段.
<sql id="selectAllColumn">id,username,password,age,gender,phone,delete_flag,create_time,update_time
</sql><select id="selectAllUser2" resultType="com.jrj.mybatis.UserInfo">select<include refid="selectAllColumn"></include>from userinfo
</select>
3. 案例练习(表白墙)
前面我们写了表白墙,但是在服务器重启之后,就会清空之前的数据,数据无法永久保留,这时候就需要引入MyBatis了,我们需要把数据存储在数据库中.
3.1 配置文件
spring:application:name: vindicatewall# 数据库连接配置datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: qwe123524driver-class-name: com.mysql.cj.jdbc.Drivermybatis:configuration: # 配置打印 MyBatis⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #配置驼峰⾃动转换
需要配置的选项有这几个,第一个是数据库相关配置,包括数据库url,用户名,密码,MySQl驱动类.其次,需要配置MyBatis中的日志打印和驼峰自动转换.
3.2 Mapper层代码
@Mapper
public interface MessageMapper {@Insert("insert into message_info (`from`,`to`,`message`) values " +"(#{from},#{to},#{message})")public Integer updateMessage(Message message);@Select("select * from message_info")public List<Message> selectAllMessage();
}
3.3 Service层代码
@Service
public class MessageService {@Autowiredpublic MessageMapper messageMapper;public Integer updateMessage(Message message){return messageMapper.updateMessage(message);}public List<Message> selectAllMessage(){return messageMapper.selectAllMessage();}
}
3.4 Controller层代码
@RestController
@RequestMapping("/messagewall")
public class MessageController {@Autowiredpublic MessageService messageService;@RequestMapping("/publish")public Boolean updateMessage(Message message){if (StringUtils.hasLength(message.getFrom())&&StringUtils.hasLength(message.getTo())&&StringUtils.hasLength(message.getMessage())){messageService.updateMessage(message);return true;}return false;}@RequestMapping("/getlist")public List<Message> selectAllMessage(){return messageService.selectAllMessage();}
}
Postman测试后端代码:


数据库已更新:

相关文章:
[Spring] MyBatis操作数据库(进阶)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
【Websim.ai】一句话让AI帮你生成一个网页
【Websim.ai】一句话让AI帮你生成一个网页 网站链接 websim.ai 简介 websim.ai接入了Claude Sonnet 3.5,GPT-4o等常用的LLM,只需要在websim.ai的官网指令栏中编写相关指令,有点类似大模型的Prompt,指令的好坏决定了网页生成的…...
云计算实训16——关于web,http协议,https协议,apache,nginx的学习与认知
一、web基本概念和常识 1.Web Web 服务是动态的、可交互的、跨平台的和图形化的为⽤户提供的⼀种在互联⽹上浏览信息的服务。 2.web服务器(web server) 也称HTTP服务器(HTTP server),主要有 Nginx、Apache、Tomcat 等。…...
2024年必备技能:小红书笔记评论自动采集,零基础也能学会的方法
摘要: 面对信息爆炸的2024年,小红书作为热门社交平台,其笔记评论成为市场洞察的金矿。本文将手把手教你,即便编程零基础,也能轻松学会利用Python自动化采集小红书笔记评论,解锁营销新策略,提升…...
【Gitlab】SSH配置和克隆仓库
生成SSH Key ssh-keygen -t rsa -b 4096 私钥文件: id_rsa 公钥文件:id_rsa.pub 复制生成的ssh公钥到此处 克隆仓库 git clone repo-address 需要进行推送和同步来更新本地和服务器的文件 推送更新内容 git push <remote><branch> 拉取更新内容 git pull &…...
[Day 35] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈的分布式存儲技術 區塊鏈技術自2008年比特幣白皮書發表以來,已經成為一種革命性的技術,帶來了許多創新。區塊鏈本質上是一個去中心化的分布式賬本,每個節點都持有賬本的副本,並參與記錄和驗證交易。分布式存儲是區塊鏈的重…...
Vue 3 中使用 inMap.js 实现蜂窝热力图的可视化
本文由ScriptEcho平台提供技术支持 项目地址:传送门 Vue 3 中使用 inMap.js 实现蜂窝热力图的可视化 应用场景介绍 蜂窝热力图是一种可视化技术,用于在地图上显示数据的分布情况。它将数据点划分为六边形单元格,并根据单元格内数据的密度…...
nginx隐藏server及版本号
1、背景 为了提高nginx服务器的安全性,降低被攻击的风险,需要隐藏nginx的server和版本号。 2、隐藏nginx版本号 在 http {—}里加上 server_tokens off; 如: http {……省略sendfile on;tcp_nopush on;keepalive_timeout 60;tcp_nodelay o…...
Oracle DBMS_XPLAN包
DBMS_XPLAN 包的解释和关键点 DBMS_XPLAN 包是 Oracle 数据库中一个重要的工具,它允许数据库管理员和开发人员以各种方式显示 SQL 语句的执行计划,这对于 SQL 优化和性能诊断至关重要。以下是主要函数及其描述: 用于显示执行计划的主要函数…...
【ffmpeg命令入门】分离音视频流
文章目录 前言音视频交错存储概念为什么要进行音视频交错存储:为什么要分离音视频流: 去除音频去除视频 总结 前言 FFmpeg 是一款强大的多媒体处理工具,广泛应用于音视频的录制、转换和流媒体处理等领域。它支持几乎所有的音频和视频格式&am…...
小红书笔记评论采集全攻略:三种高效方法教你批量导出
摘要: 本文将深入探讨如何利用Python高效采集小红书平台上的笔记评论,通过三种实战策略,手把手教你实现批量数据导出。无论是市场分析、竞品监测还是用户反馈收集,这些技巧都将为你解锁新效率。 一、引言:小红书数据…...
实战:ZooKeeper 操作命令和集群部署
ZooKeeper 操作命令 ZooKeeper的操作命令主要用于对ZooKeeper服务中的节点进行创建、查看、修改和删除等操作。以下是一些常用的ZooKeeper操作命令及其说明: 一、启动与连接 启动ZooKeeper服务器: ./zkServer.sh start这个命令用于启动ZooKeeper服务器…...
linux运维一天一个shell命令之 top详解
概念: top 命令是 Unix 和类 Unix 操作系统(如 Linux、macOS)中一个常用的系统监控工具,它提供了一个动态的实时视图,显示系统的整体性能信息,如 CPU 使用率、内存使用情况、进程列表等。 基本用法 root…...
大模型微调:参数高效微调(PEFT)方法总结
PEFT (Parameter-Efficient Fine-Tuning) 参数高效微调是一种针对大模型微调的技术,旨在减少微调过程中需要调整的参数量,同时保持或提高模型的性能。 以LORA、Adapter Tuning 和 Prompt Tuning 为主的PEFT方法总结如下 LORA 论文题目:LORA:…...
Spark+实例解读
第一部分 Spark入门 学习教程:Spark 教程 | Spark 教程 Spark 集成了许多大数据工具,例如 Spark 可以处理任何 Hadoop 数据源,也能在 Hadoop 集群上执行。大数据业内有个共识认为,Spark 只是Hadoop MapReduce 的扩展(…...
WPF多语言国际化,中英文切换
通过切换资源文件的形式实现中英文一键切换 在项目中新建Language文件夹,添加资源字典(xaml文件),中文英文各一个。 在资源字典中写上想中英文切换的字符串,需要注意,必须指定key值,并且中英文…...
Halcon深度学习分类模型
1.Halcon20之后深度学习支持CPU训练模型,没有money买显卡的小伙伴有福了。但是缺点也很明显,就是训练速度超级慢,推理效果也没有GPU好,不过学习用足够。 2.分类模型是Halcon深度学习最简单的模型,可以用在物品分类&…...
洗地机哪种牌子好?洗地机排行榜前十名公布
洗地机市场上品牌琳琅满目,每个品牌都有其独特的魅力和优势。消费者在选择时,往往会根据自己的实际需求、预算以及对产品性能的期望来做出决策。因此,无论是哪个品牌的洗地机,只要能够满足用户的清洁需求,提供便捷的操…...
C++中的虚函数与多态机制如何工作?
在C中,虚函数和多态机制是实现面向对象编程的重要概念。 虚函数是在基类中声明的函数,可以在派生类中进行重写。当基类的指针或引用指向派生类的对象时,通过调用虚函数可以实现动态绑定,即在运行时确定要调用的函数。 多态是指通…...
《LeetCode热题100》---<哈希三道>
本篇博客讲解 LeetCode热题100道中的哈希篇中的三道题。分别是 1.第一道:两数之和(简单) 2.第二道:字母异位词分组(中等) 3.第三道:最长连续序列(中等) 第一道࿱…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
SQL注入篇-sqlmap的配置和使用
在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap,但是由于很多朋友看不了解命令行格式,所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习,链接:https://wwhc.lanzoue.com/ifJY32ybh6vc…...

