12、Mybatis中用#{}和${}获取输入参数的区别
2018-01-14 10:13
513 查看
#{}和
${}都可以从接口输入中的map对象或者pojo对象中获取输入的参数值。例如:
<mapper namespace="com.lzj.mybatis.dao.UserDao"> <select id="getUser" resultType="com.lzj.mybaits.bean.User"> select * from users where name=#{name} and password=#{password} </select> </mapper>
或者
<mapper namespace="com.lzj.mybatis.dao.UserDao"> <select id="getUser" resultType="com.lzj.mybaits.bean.User"> select * from users where name=${name} and password=${password} </select> </mapper>
上面两种形式都可以通过name和pssword条件查询用户的信息。但是上面两种形式是有本质区别的:Mybatis在处理形式时,会直接把{name}和password获取的值拼接在sql中,例如{name}的值为”lzj”,${password}的值为”123456”,即mybatis直接处理sql语句为:
select * from users where name='lzj'and password='123456'
mybatis在处理#{}形式时,会通过jdbc中的PreparedStatement先预编译sql语句为下列形式:
select * from users where name=? and password=?
然后在用PreparedStatement把对应占位符处的值代替占位符。
{}比${}的优势
name和{password}取出的值直接拼装在sql语句中,会有安全问题。例如name对应的值为:
"lzj"#, 则{name}获取到的值为`"lzj"#`。此时根本不用管password的值为什么了,例如password的值为"XXXX",则{password}获取到值为”XXXX”。mybatis会拼接sql为:
select * from users where name='lzj'# and password='XXXX'
由于sql中# 表示注释的意思,所以mybatis就把上面的语句翻译成了
select * from users where name='lzj'
执行此条语句,根本不再用关系password的值是什么了,因此会有安全问题。
但是用#{}的形式就不会出现这种情况,对于#{}的形式,mybatis会先提前预编译sql语句,然后在将参数设置到sql语句中,防止sql注入。
${}比#{}的优势
大多数情况下,我们应使用#{}的形式,但在有些地方确不成立。原生jdbc不支持占位符的地方我们就可以使用${}进行取值。比如表的名字处不可以使用占位符,下面是不可以的
select * from #{users}
表名字处不能使用占位符,此时要用下面的形式:
select * from ${users}
例如order by 排序的地方不可以用,下面的形式不可以用
select * from users order by #{name}
应该使用
select * from users order by ${name}
{}其它丰富用法
在mybatis用#{}处理获取输入的参数时,还可以指定其它属性,例如#{name, javaType=String, jdbcType=null}, 如
#{amount, javaType=Double, jdbcType=NUMERIC,numericScale=3}下面介绍常用的属性
javaType :表明传入参数的类型
jdbcType:表明对应数据库中的类型,一般用来处理传入的参数为空的情况。例如:
<select id="getUser" resultType="com.lzj.mybaits.bean.User"> select * from users where name=#{name} </select>
当name参数传入的值为null时,mybatis会默认传入的name值的类型为数据库other类型 ,对于oracle数据库,不能处理other类型的字段,因此会报不能识别的错误。此时就可以用jdbcType属性指定类型,如
<select id="getUser" resultType="com.lzj.mybaits.bean.User"> select * from users where name=#{name, jdbcType=null} </select>
当传入的name值的类型为null时,在oracle数据库中会把name字段的值当空来处理。
当name参数传入的值为null时,mybatis会默认传入的name值的类型为数据库other类型 对于mysql数据库,会自动把other类型当做null类型来处理,因此对于mysql数据库中可不用指定jdbcType=null属性,当然也可以指定。
另外,由于在mybatis中默认配置把传入的NULL值类型映射到数据中的other类型,也可以在mybatis的配置文件中指定全局的把传入的NULL类型的参数映射到数据库中指定的类型。例如:
<settings> <setting name="jdbcTypeForNull" value="NULL"/> </settings>
本文中在conf.xml配置文件中,加上如上配置,当传入的参数为NULL时,mybatis默认映射到数据库中的类型就是NULL类型。
numericScale:对于java中浮点类型,当传入数据库时可能有若干小数,通过指定numericScale=3,可以指定传入数据库的字段为数值类型,并且只有小数点数后三位。
关于sql注入的问题,参考http://blog.csdn.net/javy_codercoder/article/details/49276653
相关文章推荐
- Mybatis参数获取时$与#的区别
- SpringMVC和Mybatis(二)参数绑定、和Struts区别
- page,session,application的请求区别+page,session的参数放置与获取
- MyBatis更新数据(输入参数类型为Map)
- Mybatis传递单个参数(string)时,获取参数失败
- ibatis中输入/输出各种类型的参数分析及#与$区别
- Mybatis框架中Mapper文件传值参数获取。【Mybatis】
- MyBatis—调用mysql存储过程 带输出输入参数
- jenkins Build Flow job 输入参数获取和传递
- Mybatis 获取不到接口参数问题
- 2017_12_15 js获取项目路径,js调用问题,jsp获取js传递url中参数
- 利用pywinauto模块打开一个应用,输入参数,点击应用中的按钮,获取数据
- Mybatis动态Sql的Foreach遍历拼接输入参数中的List或数组
- MyBatis排序时使用order by 动态参数时需要注意,用$而不是#, #{}和${}的区别以及order by注入问题
- mybatis调用存储过程的例子,含输入输出参数
- MyBatis教程之三多参数的获取方式
- MyBatis映射文件中用#和$传递参数的特点
- Controller中获取输入参数注解使用总结
- service和doXX方法区别、Http请求头案例、获取请求的传递参数
- 2017_11_28 mybatis多参数传入,以及#,$的区别