当前位置: 首页 > news >正文

MyBatis中#{}和${}的区别

目录

前言

1、处理参数的方式不同

2、${}的优点

3、SQL注入问题

4、like查询问题


前言

#{}和${}都可以在MyBatis中用来动态地接收参数,但二者在本质上还是有很大的区别。

1、处理参数的方式不同

${} :预编译处理

MyBatis在处理#{}时,会将SQL语句中的#{}替换为?,即占位符,然后使用PreparedStatement的set方法来赋值。

代码示例:

    <select id="getUserByID" resultType="com.example.demo.model.UserInfo">select * from userinfo where id=#{id}</select>

查看程序运行期间MyBatis打印的日志:

#{} :直接替换

MyBatis在处理${}时,会直接将SQL语句中的${}替换为参数的值。

代码示例:

    <select id="getUserByID" resultType="com.example.demo.model.UserInfo">select * from userinfo where id=${id}</select>

查看程序运行期间MyBatis打印的日志:

使用${}接收int类型的参数时是不会报错的,但是用来接收String类型的参数时代码就会报错:

代码示例:

    <!-- 根据用户名查询用户信息 --><select id="getUserByName" resultType="com.example.demo.model.UserInfo">select * from userinfo where username=${name}</select>

查看程序运行期间MyBatis打印的日志:

 "orange"是userinfo表中的一个用户名,在查询时需要加上单引号才能查询成功:

2、${}的优点

使用${}可以实现对查询结果的动态排序(升序/降序);而使用#{}则不能实现,如果传递的参数是String类型,#{}会对参数加单引号,就会出现SQL语句错误。

代码示例:

    <!-- 查询所有用户并排序 --><select id="getAll" resultType="com.example.demo.model.UserInfo">select * from userinfo order by ${order}</select>

如果使用#{}时,最终的SQL语句为:select * from userinfo order by id 'desc'

3、SQL注入问题

由于${}是直接替换参数,不会给参数添加单引号,因此会导致SQL语句错误,如果非要使用${},就需要手动对参数添加单引号:

但这样又会带来SQL注入的问题:

代码示例:

    <!-- 登录功能 --><select id="login" resultType="com.example.demo.model.UserInfo">select * from userinfo where username='${username}' and password='${password}'</select>

传入参数:"' or 1 = '1"

表中用户的正确用户名和密码:

查询结果:

而使用#{}就不会出现SQL注入的问题:

 

结论:能使用#{}就使用#{}!如果非要使用${},那么一定要进行参数校验。

4、like查询问题

在进行like查询时,使用#{}会报错:

代码示例:

    <select id="getUserByLike" resultType="com.example.demo.model.UserInfo">select * from userinfo where username like '%#{msg}%'</select>

此时最终的SQL语句为: select * from userinfo where username like '%‘a'’%'

而使用${}时,虽然可以达到目的,成功查询到数据,但是${}会有SQL注入问题,使用时需要进行参数校验,而用户输入的内容则是多种多样的,我们无法全部校验。

为了解决这个问题,就需要使用MySQL的内置函数concat()来处理:

    <select id="getUserByLike" resultType="com.example.demo.model.UserInfo">select * from userinfo where username like concat('%',#{msg},'%')</select>

相关文章:

MyBatis中#{}和${}的区别

目录 前言 1、处理参数的方式不同 2、${}的优点 3、SQL注入问题 4、like查询问题 前言 #{}和${}都可以在MyBatis中用来动态地接收参数&#xff0c;但二者在本质上还是有很大的区别。 1、处理参数的方式不同 ${} &#xff1a;预编译处理 MyBatis在处理#{}时&#xff0c…...

ElementUi的使用

ElementUi使用说明 element ui安装与配置 npm i element-ui –S项目入口文件main.js 导入 Element-UI 相关资源// 导入组件库 import ElementUI from element-ui; // 导入组件相关样式 import element-ui/lib/theme-chalk/index.css; // 配置 Vue 插件 Vue.use(ElementUI);文档…...

termux手机端安装mysql(MariaDB)

目录1 下载MariaDB2 配置MariaDB3 启动MariaDB服务器查看进程pid杀死进程4 登录 Mysqltermux用户登录MySQLroot用户登录MySQL5 配置 MariaDB 远程登录创建一个可远程登录的用户&#xff1a;用户授权&#xff1a;刷新授权&#xff1a;6 停止 MariaDB 服务器7 可选&#xff0c;但…...

Python枚举类定义和使用(详解版)

一些具有特殊含义的类&#xff0c;其实例化对象的个数往往是固定的&#xff0c;比如用一个类表示月份&#xff0c;则该类的实例对象最多有 12 个&#xff1b;再比如用一个类表示季节&#xff0c;则该类的实例化对象最多有 4 个。 针对这种特殊的类&#xff0c;Python 3.4 中新…...

京东HBase异地多活调研

京东HBase平台架构 HBase Replication原理 HBase的Replication是基于WAL日志文件的&#xff0c;在主集群中的每个RegionServer上&#xff0c;由ReplicationSource线程来负责推送数据&#xff0c;在备集群的RegionServer上由ReplicationSink线程负责接收数据。ReplicationSourc…...

【LeetCode】剑指 Offer 18. 删除链表的节点(题目一) p119 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/shan-chu-lian-biao-de-jie-dian-lcof/ 1. 题目介绍&#xff08;18. 删除链表的节点&#xff09; 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 注意&…...

SpringMVC异步请求

背景 Tomcat等应用服务器的连接线程池实际上是有限制的&#xff1b;每一个连接请求都会耗掉线程池的一个连接数&#xff1b;如果某些耗时很长的操作&#xff0c;如对大量数据的查询操作、调用外部系统提供的服务以及一些 IO 密集型操作等&#xff0c;会占用连接很长时间&#…...

这七个100%提高Python代码性能的技巧,一定要知道

B站|公众号&#xff1a;啥都会一点的研究生 相关阅读 整理了几个100%会踩的Python细节坑&#xff0c;提前防止脑血栓 整理了十个100%提高效率的Python编程技巧&#xff0c;更上一层楼 Python-列表&#xff0c;从基础到进阶用法大总结&#xff0c;进来查漏补缺 Python-元组&…...

计算机网络笔记、面试八股(五)—— 浏览器输入URL

本章目录5. 从输入URL到浏览器显示页面过程中都发生了什么5.1 URL输入5.2 DNS解析5.2.1 域名的等级5.2.2 DNS解析的流程5.2.3 DNS查询方式5.3 建立TCP连接5.4 发送HTTP/HTTPS请求5.5 服务器处理请求并返回HTTP响应5.6 浏览器解析渲染页面5.7 HTTP请求结束&#xff0c;断开TCP连…...

【速记】快速调通算法项目的环境

1.创建新的conda环境&#xff0c;避免把原有的环境给搞坏。 在CMD中执行&#xff0c;而不是在anaconda的命令行中执行&#xff1a; conda create -n 环境名 --offline python3.8 2.在pycharm中配置conda环境&#xff1a; setting->Project Interpreter->齿轮->add-&g…...

开放开源开先河(上)

目录 1.唯一性定义品牌 2.打造爆款塑造品牌 3.构筑生态体系传播品牌 2022年7月28日&#xff0c;以“软件定义世界 开源共筑未来”为主题的全球数字经济大会开放原子开源峰会在北京开幕&#xff0c;承办主峰会和为捐赠人进行授牌仪式的开放原子开源基金会再次进入公众视野。基金…...

TencentOS 3.1安装MySQL 8.0.32

到官网下载安装包&#xff1a;https://dev.mysql.com/downloads/mysql/ 使用如下命令解包。 tar xf mysql-8.0.32-1.el8.x86_64.rpm-bundle.tar 使用rpm -qa |grep mysql 和rpm -qa |grep mariadb检查是否安装过mysql 如果有&#xff0c;使用下命令移除&#xff1a; rpm -e …...

Javascript的API基本内容(五)

一、js组成 JavaScript的组成 ECMAScript: 规定了js基础语法核心知识。 比如&#xff1a;变量、分支语句、循环语句、对象等等 Web APIs : DOM 文档对象模型&#xff0c; 定义了一套操作HTML文档的API BOM 浏览器对象模型&#xff0c;定义了一套操作浏览器窗口的API 二、loc…...

分层测试(2)单元测试【必备】

1. 什么是单元测试&#xff1f; 对代码中的逻辑隔离的最小代码片段进行测试&#xff0c;验证其逻辑是否符合预期&#xff0c;单元可以是函数&#xff0c;方法&#xff0c;类&#xff0c;功能模块。 2. 单元测试的优点 掌握代码&#xff1a;单元测试允许开发人员了解单元提供…...

代码随想录算法训练营day45 |动态规划之背包问题 70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数

day4570. 爬楼梯 &#xff08;进阶&#xff09;1. 确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp数组322. 零钱兑换1. 确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组279.完全平方数1. 确…...

秒懂算法 | 基于图神经网络的推荐算法

图神经网络(Graph Neural Networks,GNN)是近几年兴起的学科,用来作推荐算法自然效果也相当好,但是要学会基于图神经网络的推荐算法之前,需要对图神经网络自身有个了解。 图卷积网络(Graph Convolutional Networks,GCN)提出于2017年。GCN 的出现标志着图神经网络的出现。深度学习…...

CANoe TC8测试脚本的结构介绍

CANoe TC8脚本是通过vTESTstudio平台编写。每个协议(ARP\ICMPv4\IPv4\UDP\TCP\SOMEIP\DHCP)都有自己的vtt文件。每个vtt文件的测试树结构为: Test Fixture Fixture Preparation Test Case Test Case … Test Case Test Case Fixture Completion 当Test Fixture里的Test Case…...

DP(4)--区间DP

将n(1≤n≤200)堆石子绕圆形操场摆放&#xff0c;现要将石子有次序地合并成一堆。 规定每次只能选相邻的两堆石子合并成新的一堆&#xff0c;并将新的一堆的石子数&#xff0c;记为该次合并的得分。 (1)选择一种合并石子的方案&#xff0c;使得做n-1次合并&#xff0c;得分的总…...

【C语言】“qsort函数详解”与“使用冒泡思想模拟使用qsort”

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨qsort的介绍&#xff1a;一、qsort函数的使用✨比较int类型数据比较字符型数据比较结构体数据冒泡思想…...

接口自动化框架---升级版(Pytest+request+Allure)

目录&#xff1a;导读 一、简单介绍 二、目录介绍 三、代码分析 写在最后 接口自动化是指模拟程序接口层面的自动化&#xff0c;由于接口不易变更&#xff0c;维护成本更小&#xff0c;所以深受各大公司的喜爱。 第一版入口&#xff1a;接口自动化框架(PytestrequestAllure…...

别再乱接Type-C了!手把手教你设计一个5V/5A的稳定电源模块(附电路图)

5V/5A Type-C电源模块实战设计指南&#xff1a;从选型到避坑全解析 Type-C接口凭借其正反插拔的便利性&#xff0c;已成为现代电子设备的标配。但许多DIY爱好者在自制Type-C电源模块时&#xff0c;常遇到供电不稳、接口烧毁甚至设备损坏的问题。本文将带你从零设计一个稳定可靠…...

数学学习者的终极指南:如何高效利用开源资源库构建完整知识体系

数学学习者的终极指南&#xff1a;如何高效利用开源资源库构建完整知识体系 【免费下载链接】awesome-math A curated list of awesome mathematics resources 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-math 在数字化学习时代&#xff0c;如何从海量的…...

避坑指南:uniapp调用支付宝授权时常见的5个错误及解决方案

Uniapp支付宝授权实战&#xff1a;5个高频错误与深度解决方案 移动应用开发中&#xff0c;第三方授权登录是提升用户体验的关键环节。作为国内主流支付平台&#xff0c;支付宝授权在电商、生活服务类App中应用广泛。但许多Uniapp开发者在实现支付宝授权功能时&#xff0c;总会遇…...

可视化拖拽组件库终极指南:响应式设计与适配方案完整解析

可视化拖拽组件库终极指南&#xff1a;响应式设计与适配方案完整解析 【免费下载链接】visual-drag-demo 一个低代码&#xff08;可视化拖拽&#xff09;教学项目 项目地址: https://gitcode.com/gh_mirrors/vi/visual-drag-demo 可视化拖拽组件库是现代低代码开发平台的…...

JDK 25模块路径在统信UOS/麒麟V10上启动失败?3步定位osgi-container冲突、jni.so符号缺失与jmod签名验签绕过方案

第一章&#xff1a;Java 25 模块化部署国产化适配方案Java 25 引入了更严格的模块系统约束与原生镜像增强能力&#xff0c;为在麒麟V10、统信UOS、openEuler等国产操作系统上实现轻量、安全、可验证的Java应用部署提供了新路径。适配核心聚焦于JVM层兼容性、模块图裁剪、国密算…...

VeraCrypt加密卷功能解析与个性化配置指南

VeraCrypt加密卷功能解析与个性化配置指南 【免费下载链接】VeraCrypt Disk encryption with strong security based on TrueCrypt 项目地址: https://gitcode.com/GitHub_Trending/ve/VeraCrypt VeraCrypt作为一款基于TrueCrypt的开源磁盘加密工具&#xff0c;提供了强…...

lite-avatar形象库部署教程:GPU共享模式下多租户数字人服务隔离方案

lite-avatar形象库部署教程&#xff1a;GPU共享模式下多租户数字人服务隔离方案 1. 项目概述 lite-avatar形象库是一个专业的数字人形象资产管理平台&#xff0c;基于HumanAIGC-Engineering/LiteAvatarGallery构建。这个库提供了150经过预训练的2D数字人形象&#xff0c;专门…...

如何用RecastNavigation构建高效AI导航系统:5个实战技巧揭秘

如何用RecastNavigation构建高效AI导航系统&#xff1a;5个实战技巧揭秘 【免费下载链接】recastnavigation Navigation-mesh Toolset for Games 项目地址: https://gitcode.com/gh_mirrors/re/recastnavigation 你是否曾为游戏中的AI角色设计路径规划而头疼&#xff1f…...

CVPR 2026 手物交互数据生成新SOTA

Project Page: https://gasaiyu.github.io/PAM.github.io/01▪ 在只给定初始姿态、目标姿态和不含外观的物体几何信息的输入下&#xff0c;如何直接生成逼真的手物交互&#xff08;HOI&#xff09;视频&#xff1f;▪ 现有方法存在一系列问题&#xff1a;姿态合成方法只能预测 …...

告别裸机UI!用LVGL 8.3给你的STM32项目做个漂亮界面(基于HAL库和SPI屏)

从零打造STM32智能界面&#xff1a;LVGL 8.3实战指南 在嵌入式开发领域&#xff0c;用户界面往往是最容易被忽视却最能直接影响用户体验的环节。想象一下&#xff0c;当你精心设计的智能家居控制面板或工业仪表&#xff0c;因为简陋的字符界面而显得廉价时&#xff0c;那种挫败…...