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的人,估计 ...
随机推荐
- 不能安装64位office提示已安装32位的
安装64位office办公软件的时候提示已经安装32位的office办公软件所以无法继续安装,但实际上之前安装的32位的office办公软件已经卸载了.问题现象截图如下: 从问题描述中,我们其实已经能 ...
- SQL 多行合并一行
select stuff((select ',' + CONVERT(VARCHAR(50),id)+'' from tab_menu group by id for xml path('')), ...
- 题解——洛谷P3390 【模板】矩阵快速幂(矩阵乘法)
模板题 留个档 #include <cstdio> #include <algorithm> #include <cstring> #define int long ...
- [ECharts] - ECharts使用中国地图
格式1: https://www.cnblogs.com/luna666/p/9007263.html (非官方) <!DOCTYPE html> <html lang=" ...
- HDU 5583 Kingdom of Black and White(暴力)
http://acm.hdu.edu.cn/showproblem.php?pid=5583 题意: 给出一个01串,现在对这串进行分组,连续相同的就分为一组,如果该组内有x个数,那么就对答案贡献x* ...
- 浅谈循环中setTimeout执行顺序问题
浅谈循环中setTimeout执行顺序问题 (下面有见解一二) 期望:开始输出一个0,然后每隔一秒依次输出1,2,3,4. for (var i = 0; i < 5; i++) { setTi ...
- JAVA基础之复识二
JAVA语言 未经本人允许禁止转载或使用 基础知识:JAVA数据类型,运算符,流程控制等 注释: // 单行注释 /* 多行连续注释 ... */ /** 文档注释,该类型的注释会生成一个html文件 ...
- js,jq获取父,兄弟,子节点整理
js获取节点 父: parentNode 获取已知节点的父节点. 子: childNodes; 得到全部子节点 children 得到全部子节点 firstChild 获得第一个子节点 lastChi ...
- Jdbc -Statement
Java提供了 Statement.PreparedStatement 和 CallableStatement三种方式来执行查询语句: PreparedStatement是用于执行参数化查询 预编译s ...
- Mac 如何安装 chromedriver
1.使用brew 命令 前提是要安装 brew 这里不做介绍 使用命令 brew install chromedriver 如上图出现错误,根据提示可以使用如下命令安装 brew cask inst ...