您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: