order by #{var} 与 order by var( #{} 与 ${} 的区别 )

群里有个小伙伴问了个我觉得很有意思的问题,在此记录下

问:order by #{date}与order by date有什么区别

理解:

#{}为占位符,比如你date这个变量值为 name desc 那么打印的sql就是 order by name desc
${}为拼接字符串,比如你date这个变量值为 name desc 那么打印的sql就是 order by "name desc",sql执行报错(错误的理解)
order by date 就是根据date这个字段排序

demo测试:

使用#{}     
	@Override
    public List<ExcelUser> selectUser(String var) {
        return userMapper.selectUser("name desc");
    }

    <select id="selectUser" resultType="com.excel.model.ExcelUser">
     select * from test_excel order by #{var}
    </select>
        
SQL打印:
        Preparing: select * from test_excel order by ? 
        Parameters: name desc(String)
        Total: 4
结果:
        执行成功
            
            
使用${}            
    @Override
    public List<ExcelUser> selectUser(String var) {
        return userMapper.selectUser("name desc");
    }

    <select id="selectUser" resultType="com.excel.model.ExcelUser">
     select * from test_excel order by #{var}
    </select> 
     
SQL打印:
        Preparing: select * from test_excel order by name desc 
        Parameters: 
		Total: 4
结果:
        执行成功
            
var为一个具体的值   
	@Override
    public List<ExcelUser> selectUser(String var) {
        return userMapper.selectUser("2021001");
    }

    <select id="selectUser" resultType="com.excel.model.ExcelUser">
     select * from test_excel order by #{var}
    </select>
        
报错信息:
        java.sql.SQLSyntaxErrorException: Unknown column '2021001' in 'order clause'
        未知列:'2021001'
原因:
        order by 是根据字段去排序的。从表中未查询到'2021001'这个列,所以报错
     

${} 与 #{} 区别

1、 处理方式不同

${} 是将参数直接替换到 SQL 中

    <select id="selectUser" resultType="com.excel.model.ExcelUser">
     select * from test_excel order by #{var}
    </select> 
     
SQL打印:
        Preparing: select * from test_excel order by name desc 
        Parameters: 
		Total: 4

#{} 则是使用占位符的方式,用预处理的方式来执行业务

    <select id="selectUser" resultType="com.excel.model.ExcelUser">
     select * from test_excel order by #{var}
    </select>
        
SQL打印:
        Preparing: select * from test_excel order by ? 
        Parameters: name desc(String)
        Total: 4

2、 取值范围不同

MyBatis既可以获取执行SQL时插入的请求参数,也可以从主配置文件加载的配置文件中获取配置参数。
#{}只能获取请求参数的值,无法获取配置参数。
${}在MyBatis初始化时能获取配置参数,如果没有,执行时再获取请求参数。

3、安全性不同

${} 会出现 SQL 注入的问题, #{} 因为是预处理方式,不会存在安全问题

使用场景:登录

使用${}登录:
    <select id="login" resultType="com.example.demo.model.UserInfo">
    	select * from userinfo where name='${name}' and password='${password}'
    </select>
    
    @Test
    void login() {
    	UserInfo userInfo = userMapper.login( "java", "java" );
    	system.out.println(userInfo);
	}
SQL打印:
    Preparing: select * from userinfo where name='java' and password='java'
结果:
    登陆成功

然而使用这种方式,在我们不知道密码的情况下却可以使用sql注入的方式使其登陆成功
    <select id="login" resultType="com.example.demo.model.UserInfo">
    	select * from userinfo where name='${name}' and password='${password}'
    </select>
    
    @Test
    void login() {
    	UserInfo userInfo = userMapper.login( "java", "'or 1='1" );
    	system.out.println(userInfo);
	}
SQL打印:
    Preparing:select * from userinfo where name='java' and password='' or 1=1
结果:
    登陆成功
使用#{}登录:
    <select id="login" resultType="com.example.demo.model.UserInfo">
    	select * from userinfo where name = #{name} and password = #{password}
    </select>
    
    @Test
    void login() {
    	UserInfo userInfo = userMapper.login( "java", "'or 1='1" );
    	system.out.println(userInfo);
	}
Sql打印:
    Preparing: select * from userinfo where name=? and password=?
    Parameters: java(String), ' or 1='1(String)
结果:
     登陆失败
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值