03-MyBatis中动态的给SQL语句赋值方式,详解占位符${}和#{}的区别和应用场景

动态的给SQL语句赋值方式

实际开发中SQL语句的参数值是不能写死到配置文件中的,应该由前端发起的请求中包含的请求参数中的数据决定

<insert id="insertCar">insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车');
</insert>

JDBC当中的占位符

在JDBC中使⽤?作为占位符,在程序的执行过程中,我们需要手动给SQL语句中的占位符传值

String sql = "insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
// 给?传值
ps.setString(1,"103");
ps.setString(2,"奔驰E300L");
ps.setDouble(3,50.3);
ps.setString(4,"2022-01-01");
ps.setString(5,"燃油⻋");
// 执行SQL语句
int count = ps.executeUpdate();

MyBatis中的占位符

#{}底层使用的是PreparedStatement对象:SQL语句中含有占位符,先对SQL语句进行预编译,然后获取值给SQL语句中的占位符 ? 传值, 可以避免SQL注入的风险

  • 占位符?传值的时候会原封不动地把值传过去(包括值的引号),即使用户提供的信息中含有sql语句关键字也无法参与编译过程,最终被当作普通的字符处理

${}底层使用的是Statement对象: 直接将获取的值拼接到SQL语句当中,然后对拼接好的SQL语句进行编译,这样做存在SQL注入的风险

  • 将动态传入的值拼接到SQL语句中后参数得引号就没有了,此时的参数值和SQL是一个整体

对于#{}(可以避免SQL注入的风险)${}(可以进⾏SQL语句关键字拼接)底层都会根据条件自动获取对应的值然后为占位符赋值,最后将获取到值传给SQL语句

<insert id="insertCar">insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},{produceTime},#{carType});
</insert>

${}的应用

数据的升序或降序

需求:通过向SQL语句中注⼊asc或desc关键字来完成查询数据的升序或降序排列

public interface CarMapper {// 查询所有的汽车信息List<Car> selectAllByAscOrDesc(String ascOrDesc);
}public class CarMapperTest {@Testpublic void testSelectAllByAscOrDesc(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);List<Car> cars = mapper.selectAllByAscOrDesc("desc");cars.forEach(car -> System.out.println(car));sqlSession.close();}
}

使用#{}会将获取到的SQL关键字(含引号)赋值给占位符?,这样会报SQL语法错误

<select id="selectAllByAscOrDesc" resultType="car">select id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType from t_car order by <!--拼接后的SQL:produce_time "desc"-->produce_time #{ascOrDesc}
</select>  

**使用${}可以将获取到的SQL关键字直接拼接到SQL语句当中完成数据的升序或降序 **

<select id="selectAllByAscOrDesc" resultType="car">selectid,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carTypefromt_carorder by<!--拼接后的SQL:produce_time desc-->produce_time ${ascOrDesc}
</select>  

拼接表名

实际开发中表的数据量非常庞大,如果将所有数据都存在一张表中的话会导致表的查询效率比较低(扫描的数据量太大),所以需要将这些数据有规律的分表存储

日志表是专门用来存储日志信息的表,如果只有一张日志表,随着每天日志的增加表中的数据会越来越多,所以需要每天生成一个日志表如以当天日期作为表名称

需求: 前端在进行查询的时候会提交⼀个具体的⽇期,后端根据这个日期动态拼接得到一个表名,最后将这个表名拼接到SQL语句中查询表中的数据

public class Log {private Integer id;private String log;private String time;//setter和getter方法@Overridepublic String toString() {return "Log{" +"id=" + id +", log='" + log + '\'' +", time='" + time + '\'' +'}';}
}
public interface LogMapper {// 根据日期名查询不同的表,获取表中所有的日志List<Log> selectAllByTable(String date);
}
public class LogMapperTest {@Testpublic void testSelectAllByTable(){SqlSession sqlSession = SqlSessionUtil.openSession();LogMapper mapper = sqlSession.getMapper(LogMapper.class);List<Log> logs = mapper.selectAllByTable("20220901");logs.forEach(log -> System.out.println(log));}
}

使用#{}的方式会将获取到的表名(含引号)赋值给占位符?,这样会报SQL语法错误

<mapper namespace="com.powernode.mybatis.mapper.LogMapper"><select id="selectAllByTable" resultType="Log"><!--select * from t_log_'20220901'-->select * from t_log_#{date}</select>
</mapper>

使用${}的方式将获取到的表名直接拼接到SQL语句之后

<!--namespace不能使用别名机制,必须写带有包名的全限定接口名称-->
<mapper namespace="com.powernode.mybatis.mapper.LogMapper"><select id="selectAllByTable" resultType="Log"><!--select * from t_log_20220901-->select * from t_log_${date}</select>
</mapper>

批量删除(in的方式)

批量删除时可以使用orin

  • or:delete from t_car where id=1 or id=2 or id=3;
  • in:delete from t_car where id in(1,2,3);

需求: 使用in关键字批量删除多条记录

public interface CarMapper {//根据id批量删除int deleteBatch(String ids);  
}@Test
public void testDeleteBatch(){CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);int count = mapper.deleteBatch("1,2,3");System.out.println("删除了⼏条记录:" + count);SqlSessionUtil.openSession().commit();
}

使用#{}的方式会将获取到的所有Id(含引号)赋值给占位符?,这样会报SQL语法错误

<delete id="deleteBatch"><!--delete from t_user where id in('1,2,3')-->delete from t_car where id in(#{ids})
</delete>

使用${}的方式将获取到的所有Id直接拼接到SQL语句之后

<delete id="deleteBatch"><!--delete from t_user where id in(1, 2, 3)  -->delete from t_car where id in(${ids})
</delete>

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

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

相关文章

基于Intel® AI Analytics Toolkits的智能视频监控系统

【oneAPI DevSummit & OpenVINODevCon联合黑客松】 跳转链接&#xff1a;https://marketing.csdn.net/p/d2322260c8d99ae24795f727e70e4d3d 目录 1方案背景 2方案描述 3需求分析 4技术可行性分析 5详细设计5.1数据采集 5.2视频解码与帧提取 5.3人脸检测 5.4行为识别…

4、Schema与数据类型优化

良好的逻辑设计和物理设计是高性能的基石&#xff0c;应该根据系统将要执行的查询语句来设计schema&#xff0c;这往往需要权衡各种因素。例如&#xff0c;反范式的设计可以加快某些类型的查询&#xff0c;但同时可能使另一些类型的查询变慢。比如添加计数表和汇总表时一种很好…

error转string

1 概述 在golang中&#xff0c;error类型是非常常见的一种数据类型。在开发过程中&#xff0c;经常会遇到需要将error类型转换成string类型的情况。本文主要介绍几种常见的golang error转string的方法。 2 使用Error()函数 在golang中&#xff0c;Error()函数是error类型的一…

Redis--15--缓存穿透 击穿 雪崩

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 缓存穿透 击穿 雪崩运行速度:1 缓存穿透问题描述:如何解决: 2 缓存击穿问题描述:如何解决: 3 缓存雪崩说明:解决方案: 缓存穿透 击穿 雪崩 问题描述: 由于海量的用…

springboot单元测试关闭日志

在logback中关闭日志 在test目录下新建文件夹resources&#xff0c;新增文件logback-test.xml文件 在logback-test.xml 文件中&#xff0c;添加内容&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <configuration><include resourc…

Java的多态性

Java是一种面向对象的编程语言&#xff0c;多态性是其核心特性之一。通过多态性&#xff0c;我们可以编写出灵活、可扩展的代码&#xff0c;提高代码的可维护性和可复用性。本文将详细介绍Java中的多态性概念、实现方式和示例代码&#xff0c;帮助读者深入理解和应用多态性。 …

一缕青丝寄相思

10年8月16日七夕节男孩向女孩表白,女孩不知道那天是七夕,也没有读懂男孩的爱,女孩在9月22日中秋,向男孩打开了心门,男孩却没有懂女孩的心思.13年后的一封问候邮件,一束女孩的长发和回不去的青春 洒满阳光的午后 转眼间看到你的笑脸 微笑着你对我说 遇上你认识我真好 你说得好莫…

33、LED呼吸灯直流电机调速

LED呼吸灯 main.c #include <REGX52.H>sbit LEDP2^0;void Delay(unsigned int t) {while(t--); }void main() {unsigned char Time,i;while(1){for(Time0;Time<100;Time) //改变亮灭时间&#xff0c;由暗到亮{for(i0;i<20;i) //计次延时{LED0; //LED亮Del…

免费HTTPS证书

什么是HTTPS呢&#xff1f;HTTPS全称为Hyper Text Transfer Protocol Secure&#xff0c;即超文本传输安全协议。它是在HTTP的基础上加入了SSL/TLS协议&#xff0c;可以对传输的数据进行加密&#xff0c;有效防止数据被第三方截取或篡改&#xff0c;从而保障了用户的信息安全。…

实时设计#N3期训练营DONE,ComfyUI中文社区@上海

作为主办方&#xff0c;我们非常高兴能够举办这次AIGC训练营&#xff0c;重点解决Comfyui的安装和入门。活动在下午1:30开始&#xff0c;在上海永兴仓库举行。 首先&#xff0c;我们向参与者介绍了本次活动的目的和安排&#xff0c;让大家对活动有一个清晰的认识。 接着&#x…

J-Link RTT的使用(原理 + 教程 + 应用 + 代码)

MCU:STM32F407VE MDK:5.29 IAR:8.32 目录--点击可快速直达 目录 写在前面什么是RTT?RTT的工作原理RTT的性能快速使用教程高级使用教程附上测试代码2019年12月27日更新--增加打印float的功能 写在前面 本文介绍了J-Link RTT的部分使用内容&#xff0c;很多地方参考和使用…

28、DS18B20温度传感器

DS18B20介绍 DS18B20是一种常见的数字温度传感器&#xff0c;其控制命令和数据都是以数字信号的方式输入输出&#xff0c;相比较于模拟温度传感器&#xff0c;具有功能强大、硬件简单、易扩展、抗干扰性强等特点 测温范围&#xff1a;-55C 到 125C 通信接口&#xff1a;1-Wire…

考研英语语法(三十八)

特殊结构的长难句分析-嵌套结构 分辨是否嵌套 先断开句子 如果一个从句没结束&#xff0c;另一个从句又开始了&#xff0c;就发生了嵌套 再一层层的看嵌套&#xff0c;进行整合 例句 The great question is who should benefit from t…

DeDeCMS v5.7 SP2 正式版 前台任意用户密码修改(漏洞复现)

1.环境搭建 PHP 5.6 DeDeCMSV5.7SP2 正式版 安装phpstudy&#xff0c;https://www.xp.cn/小皮面板 先启动Apache2.4.39和MySQL5.7.26 如果他会让你下载&#xff0c;点击是就好&#xff01; 让后点击网站—>点击创建网站 域名自己创建&#xff0c;自己取 其他的不变 点击…

6-69.鸭子也是鸟

按要求完成下面的程序&#xff1a; 1、定义一个Bird类&#xff0c;包含一个void类型的无参的speak方法&#xff0c;输出“Jiu-Jiu-Jiu”。 2、定义一个Duck类&#xff0c;公有继承自Bird类&#xff0c;其成员包括&#xff1a; &#xff08;1&#xff09;私有string类型的成员na…

SCAU:大于平均分

大于平均分 Time Limit:1000MS Memory Limit:65535K 题型: 编程题 语言: G;GCC 描述 输入10个整数&#xff0c;计算它们的平均值&#xff0c;并统计有多少个数比平均值大。输入格式 10个整数输出格式 比平均值在的数的个数输入样例 0 1 2 3 4 5 6 7 8 9输出样例 5 …

Flutter: Websocket的使用与封装

1.引入相关插件库 # websocketweb_socket_channel: ^2.4.0# 引入rxdart 解决Bad state: Stream has already been listened to.的报错问题rxdart: ^0.27.7# 状态管理*provider: ^6.0.5 2.代码编写及封装 import dart:async;import package:rxdart/subjects.dart; import pack…

西北大学计算机844考研-最后20天复习重点

西北大学计算机844考研-最后20天复习重点 ​ 我做844辅导超过400小时&#xff0c;人数超过20余人&#xff0c; 现在是2023年12月03日晚上22:33&#xff0c;这篇文章旨在帮助844众多考研学子在最后20天稳住心态&#xff0c;科学备考&#xff0c;争取获得专业课高分&#xff0c;…

使用求2个字符串最短编辑距离动态规划算法实现 git diff 算法 java 实现

测试类 MyDiffTest.java&#xff1a; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List;public class MyDiffTest {private static String path "\\xxx\\";private static List<String> lines…

Springboot启动原理解析

我们开发任何一个Spring Boot项目&#xff0c;都会用到如下的启动类 SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} } 从上面代码可以看出&#xff0c;Annotation定义&#x…