「MyBatis」数据库相关操作2

news2025/1/11 2:04:39

🎇个人主页

🎇所属专栏:Spring

🎇欢迎点赞收藏加关注哦!


#{} 和 ${}

我们前面都是采用 #{} 对参数进行赋值,实际上也可以用 ${}

客户端发送⼀条 SQL 给服务器后,大致流程如下:
1. 解析语法和语义, 校验SQL语句是否正确
2. 优化SQL语句, 制定执⾏计划
3. 执行并返回结果
一条 SQL如果走上述流程处理, 我们称为即时 SQL
#{} 用的是预编译SQL,通过 ? 占位的方式提前编译 SQL(类似 C 语言的 printf 的占位符),然后把参数填充到 SQL 语句中,它还 会根据参数类型自动拼接引号
${} 则是即时 SQL,它直接替换字符,⼀起编译 SQL。如果参数为字符串,需要加上引号
@Mapper
public interface UserInfoMapper {
    @Select("select password from userinfo where username = #{name}")
    UserInfo queryByName1(String name);

    @Select("select password from userinfo where username = '${name}'")
    UserInfo queryByName2(String name);
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void queryByName1() {
        userInfoMapper.queryByName1("lisi");
    }

    @Test
    void queryByName2() {
        userInfoMapper.queryByName2("wangwu");
    }
}

运行结果:

探讨二者的区别其实就是在讨论预编译 SQL 和即时 SQL 的区别

1. 预编译 SQL 性能更高

大多数情况下某条 SQL 语句可能会被反复调用执行,或者每次执行时只有个别值不同(比如 select 的 where 子句值不同、update 的 set 子句值不同、insert 的 values 值不同)。如果每次都需要经过上面的语法解析、SQL 优化、SQL 编译这些步骤,也就是即时 SQL,则效率显然不行
而预编译 SQL 编译一次之后就会将编译后的 SQL 语句 缓存起来 。后面再次执行这条语句时,不会再次编译(只是输入的参数不同),这样就省去解析优化等过程,提高了效率这个原理和常量池类似

2. 预编译 SQL 可以防止 SQL 注入,更安全

SQL 注入是一种通过操作输入的数据来修改事先定义好的 SQL 语句,执行代码后对服务器进行攻击的技术

${} 会有 SQL 注入的风险,所以尽量使用 #{} 完成查询

下面演示一下 SQL 注入

@Mapper
public interface UserInfoMapper {
    @Select("select password from userinfo where username = '${name}'")
    List<UserInfo> queryByName2(String name);
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void queryByName2() {
        List<UserInfo> userInfoList = userInfoMapper.queryByName2("' or 1='1");
        System.out.println(userInfoList);
    }
}

可以看到把所有的 password 都查询出来了,这显然是不合理的


3. 有一些场景 #{} 实现不了,需要用 ${},比如排序

@Mapper
public interface UserInfoMapper {
    @Select("select id,username,age,gender,phone,delete_flag,create_time,update_time " +
            "from userinfo order by id #{sort}")
    List<UserInfo> queryAllUserBySort1(String sort); //传入排序方式:排升序 or 降序

    @Select("select id,username,age,gender,phone,delete_flag,create_time,update_time " +
            "from userinfo order by id ${sort}")
    List<UserInfo> queryAllUserBySort2(String sort);
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Test
    void queryAllUserBySort1() {
        List<UserInfo> list = userInfoMapper.queryAllUserBySort1("asc");
        System.out.println(list);
    }

    @Test
    void queryAllUserBySort2() {
        List<UserInfo> list = userInfoMapper.queryAllUserBySort2("desc");
        System.out.println(list);
    }
}

#{sort} 查询结果如下:

使用  #{sort} 查询时, asc 前后会自动加上引号,导致 sql 错误;而我们不想它加引号,所以只能用 ${sort},因为这个的引号一定要我们自己手动加上去

按照 id 排降序:


模糊匹配(like 查询)

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +
 "from userinfo where username like '%#{key}%' ")
List<UserInfo> queryAllUserByLike(String key);

like 查询使用 #{} 会报错,需要用 ${},但它存在 SQL 注入的问题,所以不能直接使用

解决办法就是使用 mysql 内置函数 concat() 来实现字符串拼接

    @Select("select id,username,age,gender,phone,delete_flag,create_time,update_time " +
            "from userinfo where username like concat('%',#{key},'%')")
    List<UserInfo> queryAllUserByLike(String key);
    @Test
    void queryAllUserByLike() {
        List<UserInfo> list = userInfoMapper.queryAllUserByLike("S");
        System.out.println(list);
    }


数据库连接池

数据库连接池顾名思义,就是存放数据库连接的池子,它负责分配、管理和释放数据库连接,允许应用程序重复使用一个现有的数据库连接, 而不是再重新建立一个连接

没有使用数据库连接池的时候,每次执行 SQL 语句都要先创建一个新的连接对象, 然后执行 SQL 语句,执行完再关闭连接对象释放资源。这种重复创建连接、销毁连接的行为比较消耗资源

而如果使用数据库连接池,那么在程序启动时,会在数据库连接池中创建⼀定数量的 Connection 对象, 当客户端需要访问数据库时,会从数据库连接池中获取 Connection 对象, 然后执行 SQL, 执行完再把 Connection 放回连接池

优点:

1. 减少了网络开销
2. 资源重用
3. 提升系统的性能

常见的数据库连接池有:Hikari、Druid、C3P0、DBCP。其中 SpringBoot 默认使用的数据库连接池是 Hikari

我们也可以把默认的数据库连接池切换为 Druid,只需引入下述的依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.17</version>
</dependency>


总结

1. 命名规则:表名和字段名使用 小写字母或数字 ,单词之间以下划线分割,尽量避免出现数字开头、两个下划线、中间只出现数字这些情况

2. 表中一定有这三个字段:id、create_time、update_time。其中 id 必为主键,它的类型为 bigint unsigned,单表时自增;create_time 和 update_time 的类型均为 datetime

3. 在表查询中, 应避免使用 * 查询

4. #{} 和 ${} 区别

1. #{}:预编译处理, ${}:字符直接替换
2. #{} 可以防止 SQL 注入,${} 存在SQL注入的风险。查询语句中推荐使用 #{}
3. 但是⼀些场景 #{} 没法完成要求,比如排序功能,表名, 字段名作为参数时,需要使用 ${}
4. 模糊查询虽然 ${} 可以完成,但由于存在 SQL 注入的问题,所以通常使用 mysql 内置函数concat 来完成

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

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

相关文章

图像识别,图片线条检测

import cv2 import numpy as np # 读取图片 img cv2.imread(1.png)# 灰度化 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 边缘检测 edges cv2.Canny(gray, 100, 200) 当某个像素点的梯度强度低于 threshold1 时&#xff0c;该像素点被认为是非边缘&#xff1b;当梯度强度…

代码随想录——无重复字串的最长子串(Leetcode hot8)

题目链接 滑动窗口&#xff08;双指针&#xff09; 思路&#xff1a; 初始化: 检查字符串的长度。如果长度为0或1&#xff0c;则直接返回长度&#xff0c;因为这样的字符串本身就是无重复的。初始化两个指针 slow 和 fast&#xff0c;分别代表当前最长无重复子字符串的起始…

Django 数据库迁移:makemigrations 和 migrate 命令详解及常见问题解决

目录 1. 问题所示2. python manage.py makemigrations3. python manage.py migrate4. 拓展 1. 问题所示 最初始的状态是遇到这个问题 由于刚开始跑python web项目&#xff0c;开源项目附带的Readme&#xff0c;个别命令不太懂&#xff0c;对此详细研究其基本知识 最终的解决方…

高清无损,尽在掌握:2024年电脑录屏新标准

随着科技的飞速发展和数字化生活的普及&#xff0c;电脑录屏已经成为了我们日常工作、学习、娱乐中不可或缺的一部分。本文将带你一起探索电脑如何录屏操作。 1.福昕REC大师 链接&#xff1a;www.foxitsoftware.cn/REC/ 这款软件的便捷性令人赞叹不已。其体积小巧&#xff0…

谷歌发布会现场尴尬瞬间:AI助手Gemini展示挑战苹果

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

软件开发者的首选:最佳Bug测试工具Top 10

本篇文章介绍了以下软件bug测试管理工具&#xff1a;PingCode、Worktile、Test360、禅道、码云Gitee、优云测试、Jira、GitHub、Axosoft、Bugzilla。 在开发过程中&#xff0c;Bug的管理往往是最让人头疼的问题之一。小问题积累起来不仅会拖延项目进度&#xff0c;还可能影响到…

Win10下载安装Mysql服务

Win10下载安装MySQL 一、官网下载MySQL 1.官网地址&#xff1a; https://www.mysql.com/ 2.在官网首页拉到最下方&#xff0c;点击MySQL Community Server&#xff1a; 3.根据个人电脑的操作系统选择&#xff0c;此处以Windows x64为例&#xff0c;选择第2个&#xff0c;点击…

Nature:7个提升科研产出的实用建议

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 一个值得思考的问题是&#xff1a;层出不穷的效率工具到底是提升还是降低了科研产出&#xff1f; 大学教授萨拉 (Sara) 描述了她典型的工作日场景&#xff1a;"…

【博客23】缤果Android_XXX调试助手模板(3款)V1.0(中级篇)

超级好用的Android_XXX调试助手模板 ( Android Studio Java) 备注: 仅模板无通信协议 开发工具: android-studio-2024.1.1.12-windows.exe 目录 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 2.其他扩展展示 2.1 自定义指令集 2.2 修改自定义指令集 …

实用技巧分享:笔记本和台式电脑传输文件!

现在&#xff0c;一个人拥有两台电脑已变得十分普遍&#xff0c;通常是一台笔记本和一台台式机的组合。它们各有优势&#xff0c;比如台式机在价格相同的情况下&#xff0c;性能超过笔记本&#xff0c;还能随意更换CPU、显卡、主板等硬件&#xff0c;且使用自由。而笔记本因其便…

JAVA web项目转客户端(nativefier)(url打包客户端)

1.环境&#xff1a; windows 2.下载 node.js 3.安装node.js;记住安装目录 4.命令行进入安装目录 5.执行语句&#xff1a; npm install nativefier –g 进行安装 6.新建空文件夹用于存放生成的客户端 7.命令行进入该文件夹 8.执行语句&#xff1a; nativefier &quo…

【秋招笔试】8.11大疆秋招(第二套)-测开岗

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…

谷粒商城实战笔记-190-192商城业务-检索服务-面包屑导航

文章目录 一&#xff0c;什么是面包屑导航1&#xff0c;京东商城的面包屑2&#xff0c;面包屑是怎么产生的 二&#xff0c;面包屑导航的后台实现 这三节的主要内容是开发面包屑的前后端功能。 190-商城业务-检索服务-面包屑导航191-商城业务-检索服务-条件删除与URL编码问题192…

【Verilog HDL 入门教程】 —— 学长带你学Verilog(基础篇)

文章目录 一、Verilog HDL 概述1、Verilog HDL 是什么2、Verilog HDL产生的背景3、Verilog HDL 和 VHDL的区别 二、Verilog HDL 基础知识1、Verilog HDL 语言要素1.1、命名规则1.2、注释符1.3、关键字1.4、数值1.4.1、整数及其表示1.4.2、实数及其表示1.4.3、字符串及其表示 2、…

Spire.PDF for .NET【文档操作】演示:检测 PDF 文件是否为 PDF/A

Spire.PDF 为开发人员提供了两种方法来检测 PDF 文件是否为 PDF/A。一种是使用 PdfDocument.Conformance 属性&#xff0c;另一种是使用 PdfDocument.XmpMetaData 属性。以下示例演示了如何使用这两种方法检测 PDF 文件是否为 PDF/A。 Spire.PDF for .NET 是一款独立 PDF 控件…

详细分析JWT的基本知识(附Demo)

目录 前言1. 基本知识2. JWT验证过程3. Demo 前言 对于Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 1. 基本知识 紧凑的、U…

机器学习回归分析系列2-二项回归模型

04 二项回归模型 4.1 简介 二项回归模型用于处理二元响应变量&#xff0c;即因变量是0或1的分类变量。最常见的二项回归模型是逻辑回归&#xff0c;它可以用来预测事件发生的概率。 逻辑回归模型假设&#xff1a; 其中&#xff0c;p 是事件发生的概率&#xff0c;x1,x2,…,x…

allegro PCB设计心得笔记(四) -- 显示坐标原点和更改默认产品选项

一、修改坐标原点 Allegro PCB设计过程中&#xff0c;有时需要修改坐标原点&#xff0c;但是PCB文件不显示坐标原点&#xff0c;无法确认已修改的坐标原点是否已经修改好。 显示PCB原点的设置方法如下&#xff1a; Setup -> Design Parameter Editor&#xff0c;如下图所示&…

Kafka系统及其角色

Apache Kafka系统介绍 Apache Kafka 是由 LinkedIn 公司最初开发的一个高性能、分布式的消息传递系统。它被设计为一个可扩展、持久、分布式的流式处理平台&#xff0c;以满足 LinkedIn 在实时数据处理方面的需求 。Kafka 的诞生源于 LinkedIn 需要处理海量数据时现有消息队列系…

深度解析:NPM、PNPM、Yarn 包管理工具的介绍与对比

在前端开发中&#xff0c;包管理工具是不可或缺的一部分&#xff0c;它们帮助我们轻松管理项目依赖、发布和共享代码。NPM、PNPM、Yarn 是目前最流行的包管理工具&#xff0c;但它们各有特点和使用场景。本文将深入解析这三大包管理工具&#xff0c;帮助你选择最适合自己项目的…