Mybatis-底层是如何解决sql注入&增删改查操作--删除操作

目录

什么是sql注入?

SQL注入如何解决?

[如何在Mybatis 中实现删除操作?](#如何在Mybatis 中实现删除操作?)

方式一:

方式二:

编写单元测试方法进行测试:

小结:


什么是sql注入?

  • SQL注入:通过控制输入来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。

SQL注入最典型的场景,就是用户登录功能

登录操作的原理:

在进行登录操作时,怎么样才算登录成功呢? 如果我们查询到了数据,就说明用户名密码是对的。 如果没有查询到数据,就说明用户名或密码错误。

select **count(*)**from emp where username ='' and password=''

如果返回大于0,说明登录成功

如果返回小于0,说明登录失败

我们编写的SQL语句是基于字符串直接进行拼接的(问题所在) 。 我们输入的用户名无所谓,比如:shfhsjfhja ,而密码呢,就是我们精心设计的,如:' or '1' = '1

那最终拼接的SQL语句,如下所示:

我们知道,or 连接的条件,是或的关系,两者满足其一就可以。 所以,虽然用户名密码输入错误,也是可以查询返回结果的,而只要查询到了数据,就说明用户名和密码是正确的。--这就出现了sql注入的问题。


SQL注入如何解决?

而通过预编译SQL(select * from user where username = ? and password = ?),就可以直接解决上述SQL注入的问题。

在预编译SQL语句中,当我们执行的时候,会把整个' or '1'='1作为一个****完整的参数赋值给第2个问号(等价于对' or '1'='1进行了转义(关键之处),只当做字符串使用)

那么此时再查询时,就查询不到对应的数据了,登录失败。

注意:在以后的项目开发中,我们使用的基本全部都是预编译SQL语句。

并且使用预编译的sql性能会更高。


如何在Mybatis 中实现删除操作?

  • 需求:根据ID删除用户信息

  • SQL:delete from user where id = 5;

  • Mapper接口方法:

    方式一:

java 复制代码
/**
 * 根据id删除
 */
@Delete("delete from user where id = 5")
public void deleteById();

**这种方式执行删除操作,调用deleteById方法只能删除id为5的用户信息,因为将id直接写死在代码中了,**不可取。

方式二:

java 复制代码
/**
 * 根据id删除
 */
@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);

在Mybatis中,我们可以通过参数占位符号 #{...} 来占位,在调用deleteById方法时,传递的参数值,最终会替换占位符。

编写单元测试方法进行测试:

在单元测试类中,增加如下测试方法.

java 复制代码
@Test
public void testDeleteById(){
    userMapper.deleteById(36);
}

运行单元测试,结果如下:

运行之后,我们发现,#{...} 占位符,其实最终被替换成了 ?占位符,生成的是预编译的SQL语句。【推荐】

  • DML语句执行完毕,是有返回值的,我们可以为Mapper接口方法定义返回值来接收,如下:
java 复制代码
/**
 * 根据id删除
 */
@Delete("delete from user where id = #{id}")
public Integer deleteById(Integer id);

Integer类型的返回值,表示DML语句执行完毕影响的记录数。(小细节)

  • Mybatis的提供的符号,有两个,一个是 #{...},另一个是 ${...},区别如下:

|--------|-------------------------------------------|---------------|-----------------|
| 符号 | 说明 | 场景 | 优缺点 |
| #{...} | 占位符。执行时,会将#{...}替换为?,生成预编译SQL | 参数值传递 | 安全、性能高 (推荐) |
| ${...} | 拼接符。直接将参数拼接
SQL
语句中,存在SQL注入问题 | 表名、字段名动态设置时使用 | 不安全、性能低 |

在企业项目开发中,强烈建议使用 #{...} 。


小结:

  1. Mybatis 中执行 DML 语句时,有没有返回值?
    • 有, int类型 ,表示 DML 语句执行影响的记录数
  2. Mybatis 中 # 与 的区别是什么 ? (面试题) • # 是 **占位符** ,会替换为?生成预编译 SQL (推荐) • 字符串拼接符号 , 将参数值直接拼接在 SQL 中
相关推荐
好家伙VCC11 小时前
# MAUI 中的异步加载优化实战:从理论到高性能 UI 体验提升在现代跨平台移动开发中,*
java·python·ui
Full Stack Developme11 小时前
Java 弱引用与强引用
java·开发语言
1104.北光c°11 小时前
【重写优化 新增绘图】布谷鸟过滤器:布隆过滤器的更优缓存穿透解?
java·开发语言·后端·缓存·缓存穿透·布隆过滤器·布谷鸟过滤器
萧逸才11 小时前
【learn-claude-code】S06ContextCompact - 上下文压缩:上下文会满,你需要腾出空间
java·人工智能·ai
CCIE-Yasuo11 小时前
《永恒战士2-无双战神》无限金币版(提供apk下载)安卓Android逆向记录学习-Deepseek-AI辅助
android·java·学习·游戏
云泽野11 小时前
SpringBoot整合QQ邮箱发送邮件及微服务公共模块封装实战
java·spring boot·微服务
eSsO KERF11 小时前
MS SQL Server partition by 函数实战三 成绩排名
java
姗姗的鱼尾喵12 小时前
Java 并发编程高频面试题(含AQS/线程池/锁)
java·经验分享·面试
夫礼者12 小时前
【极简监控】选连接池送深度监控?用 Druid 补齐单体应用全局 SQL 统计的最后拼图
java·数据库·sql·druid
MyY_DO12 小时前
大麦pro 表结构分析
java