首页 > 其他分享 >#{}和${}的区别是什么

#{}和${}的区别是什么

时间:2022-08-20 20:22:50浏览次数:72  
标签:语句 name 区别 什么 SQL 编译 sql MyBatis

#{}和${}的区别是什么

动态 sql 是 MyBatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 MyBatis 会对其进行动态解析。MyBatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

区别

1)#{}是预编译处理,$ {}是字符串替换。

2)MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。

3)使用 #{} 可以有效的防止SQL注入,提高系统安全性。

项目实战中使用,请阅读我博客中Java项目实战分类中的--MySQL中in('5,6,7')只取第一个id为5对应的数据的思考一文,谢谢。

要理解记忆这个题目,我觉得要抓住两点:

(1)$ 符号一般用来当作占位符,常使用Linux脚本的同学应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的。知道了这点就能很容易区分$和#,从而不容易记错了。

(2)预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。在某些特殊场合下只能用${},不能用#{}。例如:在使用排序时ORDER BY ${id},如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法。

示例讲解

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

这个语句名为 selectPerson,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。

注意参数符号:#{id}

这就告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:

// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID = ?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);

真实项目中防止SQL注入:

Mabatis中模糊查询防止sql注入

Mysql:

select * from user where name like concat('%', #{name}, '%')

image-20220820200930746

Oracle:

select * from user where name like '%' || #{name} || '%'

SQLServer:

select * from user where name like '%' + #{name} + '%'

以下内容是对上述知识的扩展和理解

1.防止恶义SQL语法注入实例

实例一

String sql = "select * from tb_name where name = '" + varname + "' and passwd = '" + varpasswd + "' ";

如果我们把['or'1'='1]作为varpasswd传入进来.用户名随意,看看会成为什么?

select * from tb_name = 随意' and passwd = ' ' or '1'='1';

因为'1'='1'肯定成立,所以可以任何通过验证

实例二

select * from ${tableName} where name = #{name}

在这个例子中,如果表名为

user; delete user; --

则动态解析之后 sql 如下:

select * from user; delete user; -- where name = ?;

--之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

2.预编译

定义:指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。

为什么需要预编译?

JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译

1)预编译阶段可以优化 sql 的执行

预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。

2)****预编译语句对象可以重复利用

把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。

MyBatis 默认情况下,将对所有的 sql 进行预编译。

3.MyBatis sql 动态解析

MyBatis 在调用 connection 进行 sql 预编译之前,会对sql语句进行动态解析,动态解析主要包含如下的功能:

占位符的处理

动态sql的处理

参数类型校验

4.DBMS和DB的关系

DBMS数据库管理系统(databasemanagementsystem)是一种操纵和管理数据库的大型软件,是用于建立、使用和维护数据库(DB)。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库(DB)中的数据。

MySQL是一个关系型数据库管理系统。

数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合。

参考

https://www.cnblogs.com/liaowenhui/p/12217959.html

标签:语句,name,区别,什么,SQL,编译,sql,MyBatis
From: https://www.cnblogs.com/javaxubo/p/16608519.html

相关文章

  • jquery中attr方法和val方法的区别
    这几天一直在看jquery,感觉attr方法和val方法没有什么区别,经过试验,有点明白了这两个方法的区别!分享一下,如果理解错误,请大家指正!以下是源码:<!DOCTYPEhtml><html><head><......
  • 虚拟数字人制作应用有什么优势?AR服务商形象|广州华锐互动
      在应用行业方面,虚拟数字人也将带动文旅、教育、金融、医疗等行业的新变革。广州华锐互动致力于数字人底层核心技术的研发,积极推动尖端实验室科研成果的民用化、商业化,......
  • Office 365 和 Office 2019 之间的区别是什么?
    Office365和Office2019之间的区别是什么?Office365可确保你始终拥有最新的Microsoft工具。存在针对家庭和个人、中小型企业、大型企业、学校以及非营利组织的Of......
  • html元素中class属性值多个空格分格是什么意思?
    https://www.cnblogs.com/XACOOL/p/5645679.html即指定多个class,这是bootstrap常干的事,比如 <divclass="alertalert-info">请问,这两个class之间的关系是什么,二者的......
  • 再谈PHP单引号和双引号区别
    关于单引号和双引号的区别和效率问题。很多朋友了解的不是很清楚,一直以为PHP中单引号和双引号是互通的,直到有一天,发现单引号和双引号出现错误的时候才去学习研究。所以今......
  • 10.java程序出现oom如何解决?什么场景下会出现oom?
    10.java程序出现oom如何解决?什么场景下会出现oom? oom概述Outofmemory(OOM)是一种操作系统或者程序已经无法再申请到内存的状态。经常是因为所有可用的内存,包括磁盘交换......
  • 虚拟机jvm和hotspot的联系与区别
    JVM是虚拟机,总的来说是一种标准规范,虚拟机有很多实现版本。主要作用就是运行java的类文件的。而HotSpot是虚拟机的一种实现,它是sun公司开发的,是sunjdk和openjdk中自带的......
  • Vector为什么是线程安全的?
    因为官方在涉及线程不安全的操作上都加了synchronized关键字,相当于加了一把锁;这种线程安全不是绝对的,因为这种方式是方法级的,添加和删除的方法还是可以同时进行,可能存在添......
  • javascript:null和undefined的区别(chrome 104.0.5112.101)
    一,js代码:<html><head><metacharset="utf-8"/><title>测试</title></head><body><buttononclick="test()">测试</button><script>functiontest......
  • 为什么成功的人少?
    因为想要成功,想要不平凡,那你必须是个狠人,你承受痛苦的能力要比别人高很多。如果你选择了舒适,那你就等于选择了平凡。如果你不想平凡,却没有行动不去做事,不想承受痛苦,那你就......