Java神鬼莫测之MyBatis中$与#的区别(五)

举报
baidaguo 发表于 2022/05/25 22:43:53 2022/05/25
1.1k+ 0 0
【摘要】 MyBatis中$与#的区别 1.问题描述 在mybatis的动态传参中, 我们可以私用#{},传递参数,也可以使用${}传递参数, 他们有什么差别呢? 如果在mybatis中的sql语句,使用的是...

MyBatis中$与#的区别

1.问题描述

在mybatis的动态传参中, 我们可以私用#{},传递参数,也可以使用${}传递参数, 他们有什么差别呢?

如果在mybatis中的sql语句,使用的是in条件查询,则使用${}时会报错,这又是为什么呢?

2.举例说明

2.1. UserDao接口的方法

//根据字符串usernames,查询所有的User信息
public List<User> findByNames(@Param("usernames") String usernames) throws Exception;

  
 

2.2. 调用该方法

public class MybatisTest {
    @Test
    public void test01() throws Exception {
        InputStream is = Resources.getResourceAsStream("SqlMapconfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        
        //假设参数是   'lucy','tom'
        String usernames = "'lucy','tom'";
        List<User> list = userDao.findByNames(usernames);
        System.out.println(list);
    }
}

  
 

2.3.配置(映射)文件中的配置

2.3.1.使用#{}

① 修改xml设置

<mapper namespace="com.itheima.dao.UserDao">
    <!--根据字符串usernames,查询所有的User信息-->
    <select id="findByNames" resultType="com.itheima.domain.User" >
        select * from user where username in (#{usernames})
    </select>
</mapper>

  
 

② 执行删除test01()测试方法

③ 查看执行日志

DEBUG *** ==> Preparing: select * from user where username in (?) 
DEBUG *** ==> Parameters: 'lucy','tom'(String)
DEBUG *** ==> Total: 0

  
 

④ 结论

#{} 预编译完成后, 变成了占位符?, 可以预防sql攻击

2.3.2 使用${}

① 修改xml设置

<mapper namespace="com.itheima.dao.UserDao">
    <!--根据字符串usernames,查询所有的User信息-->
    <select id="findByNames" resultType="com.itheima.domain.User" >
        select * from user where username in (${usernames})
    </select>
</mapper>

  
 

② 执行删除test01()测试方法

③ 查看执行日志

<mapper namespace="com.itheima.dao.UserDao">
    <!--根据字符串usernames,查询所有的User信息-->
    <select id="findByNames" resultType="com.itheima.domain.User" >
        select * from user where username in (${usernames})
    </select>
</mapper>

  
 

② 执行删除test01()测试方法

③ 查看执行日志

DEBUG *** ==> Preparing: Preparing: select * from user where username in ('lucy','tom')
DEBUG *** ==> Parameters: 
DEBUG *** ==> Total: 2
[User{id=1, username='lucy', password='123'}, User{id=2, username='tom', password='123'}]

  
 

④ 结论

${} 会单纯的把参数值, 替代到sql语句对应位置上边. 不能预防sql攻击

3.补充

3.1 ${}的场景

  1. 作为in条件时,
  2. 参数为int类型并且数据库中字段的类型是number,
  3. 在sql语句中, 实现动态表名
  4. order by ${},动态排序字段

3.2 ${}的缺点(严重)

${}不能预防sql攻击

例设:

​ sql语句: select * from ${tablename}

​ 参数值: product; drop product;

那么你的表数据就会被无声无息的干掉了。

文章来源: baidaguo.blog.csdn.net,作者:白大锅,版权归原作者所有,如需转载,请联系作者。

原文链接:baidaguo.blog.csdn.net/article/details/118930814

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。