12、Mybatis中用#{}和${}获取输入参数的区别

#{}${} 都可以从接口输入中的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}和 passwordsql {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} 下面介绍常用的属性

  1. javaType :表明传入参数的类型
  2. 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类型。

  1. numericScale:对于java中浮点类型,当传入数据库时可能有若干小数,通过指定numericScale=3,可以指定传入数据库的字段为数值类型,并且只有小数点数后三位。

关于sql注入的问题,参考http://blog.csdn.net/javy_codercoder/article/details/49276653

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值