首页 > 其他 > 详细

Mybatis中 #{}和${}的区别

时间:2019-11-03 14:01:22      阅读:94      评论:0      收藏:0      [点我收藏+]

2019.11.01 杭州的一个面试,有问道这个问题:

 讲一下Mybatis中 #{}和${}的区别?

  情况一:只用  #{}

  <select id="getUserByNameAndPsw" resultType="com.hotel3.model.User">
        select * from USER where userName=#{userName} and userPassword =#{userPassword};
  </select>

  结果:

c.h.m.UserMapper.getUserByNameAndPsw     : ==>  Preparing: select * from USER where userName=? and userPassword =?; 
c.h.m.UserMapper.getUserByNameAndPsw     : ==> Parameters: mww(String), 123(String)
c.h.m.UserMapper.getUserByNameAndPsw     : <==      Total: 1

  结论:

    #{}会在编译期,生成两个?,作为占位符。

 

  情况二:一个用  ${} 一个用 #{}

  <select id="getUserByNameAndPsw" resultType="com.hotel3.model.User">
        select * from USER where userName=${userName} and userPassword =#{userPassword};
  </select>

   结果:

c.h.m.UserMapper.getUserByNameAndPsw     : ==>  Preparing: select * from USER where userName=mww and userPassword =?; 
c.h.m.UserMapper.getUserByNameAndPsw     : ==> Parameters: 123(String)

  结论:很显然  ${}  是直接拼成字符串的 ,#{}  是生成   ? 占位符的。

     而且 因为  userName:mww 是字符串,所以 这种写法显然也是错误的。

     会爆出如下错误:

### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘mww‘ in ‘where clause‘

  所以正确的写法是这样的:为字符串字段加上单引号 ‘ ‘

<select id="getUserByNameAndPsw" resultType="com.hotel3.model.User">
        select * from USER where userName=‘${userName}‘ and userPassword =#{userPassword};
  </select>

  结果:

c.h.m.UserMapper.getUserByNameAndPsw     : ==>  Preparing: select * from USER where userName=‘mww‘ and userPassword =?; 
c.h.m.UserMapper.getUserByNameAndPsw     : ==> Parameters: 123(String)
c.h.m.UserMapper.getUserByNameAndPsw     : <==      Total: 1

  结论:显然这种写法是正确的,从这里可以看出,编译期   ${}  是直接把参数拼结到SQL中,运行时,就只传入了一个 #{} 修饰的参数。

     ${}的这种写法还有一个安全隐患,那就是 SQL注入。

 

  情况三: ${}   SQL注入:

  <select id="getUserByNameAndPsw" resultType="com.hotel3.model.User">
        select * from USER where userName=‘${userName}‘ and userPassword =#{userPassword};
  </select>

  结果:

c.h.m.UserMapper.getUserByNameAndPsw     : ==>  Preparing: select * from USER where userName=‘‘ OR 1=1 OR ‘‘ and userPassword =?; 
c.h.m.UserMapper.getUserByNameAndPsw     : ==> Parameters: 65787682342367(String)
c.h.m.UserMapper.getUserByNameAndPsw     : <==      Total: 2

  结论:只要我们在  ${}  输入   ‘ OR 1=1 OR ‘   无论后面的密码输入什么都可以,查询到数据,这种情况就是SQL输入。

 

    在这种用法中, #{} 显然比 ${} 用法更好。那 ${} 为什么经常在  Mybatis  使用那。

    ${}正确用法:

    同时传入字段名和字段值:

User u=userService.getUserByNameAndPsw("userName,userType,userPassword",userName,userPassword);

    SQL: select ${arg0} from USER

  <select id="getUserByNameAndPsw" resultType="com.hotel3.model.User">
        select ${arg0} from USER where userName=#{userName} and userPassword =#{userPassword};
  </select>

    结果:

c.h.m.UserMapper.getUserByNameAndPsw     : ==>  Preparing: select userName,userType,userPassword from USER where userName=? and userPassword =?; 
c.h.m.UserMapper.getUserByNameAndPsw     : ==> Parameters: mww(String), 123(String)
c.h.m.UserMapper.getUserByNameAndPsw     : <==      Total: 1

    结论:

 

待续。。。。

Mybatis中 #{}和${}的区别

原文:https://www.cnblogs.com/mww-NOTCOPY/p/11777187.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!