MyBatis动态sql之${}和#{}区别
前言
接触mybatis也是在今年步入社会之后,想想也半年多了,缺没时间去系统的学习,只知道大概,也是惭愧。
不知道有多少刚毕业的同学和我一样,到现在还没仔仔细细去了解你每天都会见到使用到的框架呢?
什么?你也不知道mybatis动态sql中${}和#{}的差异?其实我也是今天才知道的,我们一起来学习一下吧。
正文
不够刺激,再增加一点前戏
在mybatis中,使用sql查询时,经常需要动态传递参数。大家往往会采用以下方式:
-- 以根据order_no 查询订单信息为例
-- ①
select * from order where order_no = #{orderNo}
-- ②
select * from order where order_no = '${orderNo}'
咦,不对!!!如果orderNo=’2017111695468435844135’,要最后执行后的结果与下面的语句执行结果一样,到底是用①还是②呢?
select * from order where order_no = '2017111695468435844135'
好吧。。。其实两种方式得到的结果是相同的。
but 在某些情况下,我们只能使用二者其一!!!
主题开始了
动态sql 是mybatis优于其他ORM框架的一个重要原因之一。
mybatis 在对 sql 语句进行预编译之前,会对 sql 进行动态解析,解析为一个BoundSql 对象,也是在此处对动态 SQL 进行处理的,使得#{}和${}在此处产生了差异。
#{}解析为一个JDBC中prepared statement的参数标记符
即:
select * from order where order_no = #{orderNo}
被解析为:
select * from order where order_no = ?
也即是,#{}被解析为一个参数占位符?.
${}则仅仅是一个纯粹的字符串替换
即:
select * from order where order_no = '${orderNo}'
被解析为:
select * from order where order_no = '2017111695468435844135'
也就是说,使用${}在预编译之前已经不包含变量name了,而#{}的变量替换是在DBMS中。
注意安全哦
能使用#{}的地方就别用${}.
reason:1.使用#{},相同的预编译sql可以重复利用,性能比${}高;
2. ${}在预编译之前已经被变量替换了,会存在sql注入问题。
例如:
select * from ${tableName} where order_no = #{orderNo}
如果从客户端传入的tableName = “order;delete order; – “,那么sql动态解析之后,预编译之前的sql将变为:
select * from order;delete order; -- where order_no = #{orderNo}
– 之后的语句被注释了,然后,sql完全大变了。。。interesting!!!**
- 表名作为变量时,必须使用${}.表名是字符串,使用 sql 占位符替换字符串时会带上单引号
'',这会导致 sql 语法错误.
再简单讲讲sql预编译
定义:
sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。
为什么需要预编译
JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译
- 预编译阶段可以优化 sql 的执行。
预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。 - 预编译语句对象可以重复利用。
把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。
MyBatis动态sql之${}和#{}区别的更多相关文章
- mybatis动态sql #和$的区别
$和#都支持动态sql:就是你传什么它就是什么 区别: 1.#可以防止sql注入在sql执行时显示 '?' 比$安全 SELECT * FROM table WHERE id = ? 2.在使用#传入 ...
- mybatis 动态sql和参数
mybatis 动态sql 名词解析 OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性, ...
- MyBatis动态Sql 的使用
Mapper.xml提示: 1:mapper包中新建一个文件:mybatis-3-mapper.dtd 2:在web app libraries/mybatis.jar/org.apache.ibat ...
- MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】
(第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...
- MyBatis 动态SQL(十二)
动态条件查询 以下是我们数据库表 tb_user 的记录: 假设现在有一个需求,就是根据输入的用户年龄和性别,查询用户的记录信息.你可能会说,这太简单了,脑袋里立马蹦出如下的 SQL 语句: SELE ...
- mybatis动态sql以及分页
1.mybatis动态sql 2.模糊查询 3.查询返回结果集的处理 4.分页查询 5.特殊字符处理 1.mybatis动态sql If.trim.foreach If 标签判断某一字段是否为空 &l ...
- mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句
mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:1. if 语句 (简单的条件判断)2. c ...
- 9.mybatis动态SQL标签的用法
mybatis动态SQL标签的用法 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么 ...
- 自己动手实现mybatis动态sql
发现要坚持写博客真的是一件很困难的事情,各种原因都会导致顾不上博客.本来打算写自己动手实现orm,看看时间,还是先实现一个动态sql,下次有时间再补上orm完整的实现吧. 用过mybatis的人,估计 ...
随机推荐
- 高级定时器TIM1&TIM8
高级定时器 初识stm32高级定时器: (1)高级控制定时器(TIM1 和 TIM8)和通用定时器在基本 ...
- Unity3D学习笔记(三十四):Shader着色器(1)
一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似. GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...
- MongoDB 基本语法笔记
MongoDB常识 MongoDB Shell是MongoDB自带的交互式Javascript shell,所以可直接执行JS脚本,用来对MongoDB进行操作和管理的交互式环境. ObjectId: ...
- 3、iptables扩展及使用
iptables/netfilter netfilter: kernel framework,位于内核中的协议框架 iptables 是规则管理命令行工具 四表:filter, nat, mangl ...
- Python pycharm 常用快捷键
快捷键 1.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性) Ctrl + Alt + Space 快速导入任意类 Ctrl + Shift + Enter 语句完成 ...
- 查看iis对应w3wp.exe显示的进程ID号
1.任务管理器,查看,选择列,选择PID(进程标识符) 2.通过cmd查询: 管理员身份运行cmd,跳转到C:\Windows\System32\inetsrv目录,然后运行appcmd list w ...
- python 排序 由大到小
import functools class Solution: # @param {integer[]} nums # @return {string} def largestNumber(self ...
- VMware网络连接模式—桥接、NAT以及仅主机模式的详细介绍和区别
在使用VMware Workstation(以下简称:VMware)创建虚拟机的过程中,配置虚拟机的网络连接是非常重要的一环,当我们为虚拟机配置网络连接时,我们可以看到如下图所示的几种网络连接模式:桥 ...
- Java String常用的两个方法
- d3 + geojson in node
d3.js本来主要是用于用“数据驱动dom”,在浏览器端,接收后端数据,数据绑定,渲染出svg. 即使是在ng中用,也是会由框架打包,供客户端下载. 那么,如果用所谓后端渲染,发布静态的svg,那就要 ...