MyBatis中${ }与#{ }有什么区别?
1、#{ }是预编译处理,MyBatis在处理#{ }时,它会将sql中的#{ }替换为?,然后调用PreparedStatement的set方法来赋值;
2、${ }是字符串替换, MyBatis在处理${ }时,它会将sql中的${ }替换为变量的值。
注意:使用${ }会导致 sql注入,不利于系统的安全性!
SQL注入:就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。常见的有匿名登录(在登录框输入恶意的字符串)、借助异常获取数据库信息等
应用场合:
1、#{ }:主要用户获取DAO中的参数数据。在映射文件的SQL语句中出现#{ }表达式,底层会创建预编译的SQL;
2、${ }:主要用于获取配置文件数据,DAO接口中的参数信息。当$出现在映射文件的SQL语句中时,创建的不是预编译的SQL,而是字符串的拼接,有可能会导致SQL注入问题.所以一般使用$接收dao参数时,这些参数一般是字段名,表名等,例如order by {column}。
注:
${}获取DAO参数数据时,参数必须使用@param注解进行修饰 ,或者 使用下标 或者 参数#{param1}形式;
#{}获取DAO参数数据时,假如参数个数多于一个可有选择的使用@param。
-——————————
作者:为生活而Coding
来源:CSDN
原文:https://blog.csdn.net/weixin\_42759709/article/details/83015890
版权声明:本文为博主原创文章,转载请附上博文链接!
mybatis中#{}和${}的区别
- # 将传入的数据 都当成一个字符串,会对 自动传入的数据 加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”.
- $将传入的数据直接显示生成在sql中。(对传入的值不做修改。不会像#{ }那样给参数加 双引号)。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by 111。 如果传入的值是id,则解析成的sql为order by id.
- #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的,就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
我觉得#与$的区别最大在于:#{} 传入值时,sql解析时,参数是带引号的,而${}穿入值,sql解析时,参数是不带引号的。
一 : 理解mybatis中 $与#
在mybatis中的$与#都是在sql中动态的传入参数。
eg:select id,name,age from student where name=#{name} 这个name是动态的,可变的。当你传入什么样的值,就会根据你传入的值执行sql语句。
二:使用$与#
#{}: 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符 。
${}: 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段 将会进行变量替换。
name—>cy
select id,name,age from student where name=#{name} -- name='cy'
select id,name,age from student where name=${name} -- name=cy
sql语句中#{},表示一个占位符。
MyBatis中${}与#{}区别
#{}
预编译SQL,类似于JAVA的预编译,例如:
String sql = "insert into info(name,age) values(?,?)";
PreparedStatement sta = con.prepareStatement(sql);
sta.setString(1, “张三”);
sta.setInt(2, 10);
只不过默认情况下会把参数当做字符串而自动添加一个双引号,例如:order by #{id},当传入的值是10时则为order by “10”。
凡是用到table、column名字的地方,都不能用#。例如:insert into/select/delete/order by等这些后面是紧跟table名字和column名字的,这些名字是不允许添加引号的。
优点在于:防止SQL注入。
${}
不会预编译,原样输出,不会额外添加任何符号。例如:order by ${id},当传入的值是10时则为order by 10。
缺点:可能发生SQL注入问题。
#{}扩展JdbcType
在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值,它会自动将Java类型 转换成 数据库的类型。
而一旦传入的是null ,程序就无法准确判断这个类型应该是什么(是Integer?是VARCHAR?还是别的?),就有可能将类型转换错误从而报错。加入jdbcType正是为了解决这样的报错。
说白了,就是从数据库中取出记录后,由于数据库的数据类型与JAVA的数据类型不一致,需要针对特定数据的特定数据类型来指定对应的JAVA类型,这就是javaType。
数据库的数据类型 BIT | FLOAT | CHAR | TIMESTAMP |
TINYINT | REAL | VARCHAR | BINARY |
SMALLINT | DOUBLE | LANGVARCHAR | VARBINARY |
INTEGER | NUMBERIC | DATE | LOANGVARBINARY |
BIGINT | DECIMAL | TIME | NULL |
OTHER | BLOB | CLOB | BOOLEAN |
UNDEFINED | NVARCHAR | NCHAR | NCLOB |
CURSOR |
方向:从Java类型转变成数据库类型。
#{}扩展javaType
JDBCType JavaType
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT Struct
REF Ref
DATALINK java.net.URL
-——————————
作者:弱即罪
来源:CSDN
原文:https://blog.csdn.net/attack\_breast/article/details/88039493
版权声明:本文为博主原创文章,转载请附上博文链接!
还没有评论,来说两句吧...