当前位置:   article > 正文

MyBatis单表查询——参数占位符${}和#{}、SQL注入、like查询_mybatis like 参数

mybatis like 参数

目录

前言: 

1、参数占位符:${}和#{}

2、SQL注入

 3、${}的优点

小结:$  VS  #:

4、like查询

 解决方案,使用MySQL的内置函数concat()来处理


前言: 

        以下文章,对于没有接触过Mybatis的小伙伴来说,需要看完这篇文章才可以继续向下执行:http://t.csdn.cn/nGTFZ

其次,我们为了更好地观察出现的问题,可以在配置文件中,配置打印MyBatis的执行SQL:

  1. # 配置打印 MyBatis 执行的 SQL
  2. logging:
  3. level:
  4. com:
  5. example:
  6. demo: debug

1、参数占位符:${}和#{}

我们在mapper的.xml文件中,进行数据库的SQL语句编写时,通常会使用${}和#{}作为参数占位符,例如:

${}:

接口:

Userinfo getById(@Param("id") Integer id);

UserMapper.xml中: 

  1. <select id="getUserById" resultType="com.example.demo.entity.Userinfo">
  2. select* from userinfo where id = ${id}
  3. </select>

 #{}:

接口:

Userinfo getByName(@Param("username") String username);

UserMapper.xml中: 

  1. <select id="getByName" resultType="com.example.demo.entity.Userinfo">
  2. select * from userinfo where username = #{username}
  3. </select>

 以上代码是没有问题,但如果当我们在.xml文件中,将${id}改为#{id},将#{username}改为${username}时,我们来测试一下【测试使用的是伪代码】:

  1. @SpringBootTest
  2. class UserMapperTest {
  3. @Autowired
  4. private UserMapper userMapper;
  5. @Test
  6. void getById() {
  7. Userinfo userinfo = userMapper.getById(1);
  8. System.out.println("查询结果:" +userinfo);
  9. }
  10. @Test
  11. void getByName() {
  12. Userinfo userinfo = userMapper.getByName("张三");
  13. System.out.println("查询结果:" +userinfo);
  14. }
  15. }

测试结果:

 id查询成功:

 username查询失败:

         从这里,其实就能看到,SQL语句是=张三,而我们在学习数据库操作时就知道,字符串类型的需要用双引号括起来~

我们来看看这里${}和#{}到底是怎么查询的呢?

        使用#{}作为参数占位符时, #{}是进行预编译处理,也就是说MyBatis在处理#{}时,会将SQL中的#{}替换为?号,如同JDBC一样,使用PreparedStatement的set方法来赋值。也就是说传过来的参数会用引号括起来,如同sql语句的:

select * from userinfo where id =  '1';

结果:

 

         使用${}作为参数占位符时,${}是进行直接替换,也就是说,MyBatis在处理${}时,直接把${}替换成变量的值,如同上图中直接是username = 张三,如同sql语句的:

${}是直接替换,就会有懂得程序的人借用这个漏洞,乘虚而入——SQL注入

什么是SQL注入呢?


2、SQL注入

假设有一个登录页面【假设数据库中刚好只有一条数据,因为有的配置下,当数据有多条时,可以执行成功,当有的配置下则无法成功】,需要输入用户名和密码:

接口:

Userinfo login(@Param("username") String name, @Param("password") String password);

XML中:

  1. <select id="login" resultType="com.example.demo.entity.Userinfo">
  2. select * from userinfo where username = #{username} and password = ${password}
  3. </select>

 用户名咱们正常使用#{},在密码这里,咱们做一点手脚:使用${}参数占位符~

测试:

  1. @Test
  2. void login() {
  3. String name = "张三";
  4. String password = " 'xx' or 1=1";
  5. Userinfo userinfo = userMapper.login(name,password);
  6. System.out.println("登陆状态:"+(userinfo==null?"失败":"成功"));
  7. }

结果:

 使用错误的密码居然登陆成功了,这种问题,如果放在实际生活中,大家想想,多恐怖啊!

咱们来看看他实际执行的SQL语句:

控制台,试试看:

为什么说需要一条数据呢?因为,如果有多条,我的这个案例会将多所有的信息全部输出,如下:

 而我们的接收写的是一个对象,而不是用聚合去接收~

结论:用于查询的字段,尽量使用#{}预查询的方式

那${}就没有优点了吗?

还是有的,如下: 


 3、${}的优点

 查询中,带有SQL关键字,需要使用${}

使用#{}会报错:

接口:

List<Userinfo> sortAll(@Param("sort") String userinfo);

 xml:

  1. <select id="sortAll" resultType="com.example.demo.entity.Userinfo">
  2. select * from userinfo order by id #{sort}
  3. </select>

测试:

  1. @Test
  2. void sortAll() {
  3. String sort = "desc";
  4. List<Userinfo> userinfos = userMapper.sortAll(sort);
  5. System.out.println(userinfos);
  6. }

 结果:

 相当于在控制台输入:

 select * from userinfo order by id 'desc';

换成${}再测试:

 

         这样子查询,必须要求传输的值是可以穷举的【如同排序要么是asc,要么是desc】,在使用之前需要对传递的值进行安全性验证~

小结:$  VS  #:

  1. $存在SQL注入的问题,而#不存在
  2. $直接替换,#是预处理

4、like查询

like查询在使用#{}时,会报错:

举例:

接口:

List<Userinfo> likename(@Param("username") String username);

xml:

  1. <select id="likename" resultType="com.example.demo.entity.Userinfo">
  2. select * from userinfo where username like "%#{username}%"
  3. </select>

测试:

  1. @Test
  2. void likename() {
  3. String username = "a";
  4. List<Userinfo> userinfos = userMapper.likename(username);
  5. System.out.println(userinfos);
  6. }

结果:

如同在控制台输入:

 

 正确的控制台应该输入什么:

 解决方案,使用MySQL的内置函数concat()来处理

xml代码:

  1. <select id="likename" resultType="com.example.demo.entity.Userinfo">
  2. select * from userinfo where username like concat('%',#{username},'%')
  3. </select>

运行:

好啦,本期到这里结束 啦,咱们下期再见咯~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/432490
推荐阅读
相关标签
  

闽ICP备14008679号