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的人,估计 ...
随机推荐
- 【索引失效】什么情况下会引起MySQL索引失效
索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 注意:要想使用or,又想让索引生效,只能将or条件 ...
- HDFS 的垃圾回收配置
HDFS的垃圾回收 的默认配置的 0,也就是说,如果你不小心误删除了某样东西,那么这个操作是不可恢复的. 但是如果配置了HDFS的垃圾回收机制,那么删除的东西就可以在垃圾箱中保存一段你配置的时间,等 ...
- 通过sql语句修改表的结构
1.修改表的列名 oracle: ALTER TABLE 表名 RENAME COLUMN 列名 TO 新列名sqlserver:exec sp_rename '[表名].[列名]','[表名].[新 ...
- AngularJS 笔记2
2017-03-23 本文更新链接: http://www.cnblogs.com/daysme/p/6613071.html $http angularjs中的ajax 向服务器请求数据 1/2 后 ...
- 用户管理--借鉴技术大牛ken
本节内容 useradd userdel usermod groupadd groupdel 用户管理 为什么需要有用户? 1. linux是一个多用户系统 2. 权限管理(权限最小化) 用户:存在的 ...
- AmazeUI学习
http://amazeui.org/ 相比于其他国外的框架而言,Amaze UI更关注中文排版,被前端工程师称为最懂中文的前端框架. Amaze UI受欢迎的一个重要的原因是:文档非常完善,适合各阶 ...
- 跳跳虎回家(国庆10.1模拟赛T2)
题目: [题目描述] 跳跳虎在外面出去玩忘了时间,现在他需要在最短的时间内赶回家. 跳跳虎所在的世界可以抽象成一个含有 n 个点的图(点编号从 1 到 n ),跳跳虎现在在 1 号点,跳跳虎的家在 n ...
- 利用logstash从mysql同步数据到ElasticSearch
前面一篇已经把logstash和logstash-input-jdbc安装好了. 下面就说下具体怎么配置. 1.先在安装目录bin下面(一般都是在bin下面)新建两个文件jdbc.conf和jdbc. ...
- django表单的Widgets
不要将Widget与表单的fields字段混淆.表单字段负责验证输入并直接在模板中使用.而Widget负责渲染网页上HTML表单的输入元素和提取提交的原始数据.widget是字段的一个内在属性,用于定 ...
- OpenModelica中simulate的用法
先把官网上的说明文档放上来: simulate simulates a modelica model by generating c code, build it and run the simula ...