Statement 和 PreparedStatement的区别

本文探讨了Statement和PreparedStatement在Java中的区别。Statement适合执行静态SQL,而PreparedStatement不仅能够防止SQL注入,还支持预编译和参数类型设置,提高代码可维护性和效率。通过设置参数类型,PreparedStatement可以进行更严格的输入验证,降低安全风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先看一下他们倆的创建方式

{
    	Connection connection = InitJdbcConnection.getConnection();
        try {
            Statement statement = connection.createStatement();
            PreparedStatement preparedStatement = connection.prepareStatement("xxx");
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
 
}
  • Statement 是通过createXX创建出来的, 动词+名词 Connection对象已经通过函数名告诉我们, Statement是有独立性的
    • 对于一个Connection来说,一个Statement对象可以执行多条不同的SQL

  • PreparedStatement 是直接点出来的, 其没有方法动词, 不知道的还能以为他是Connection的成员变量;但实际上他也是一个函数;
    • Prepared 的直接意思就是 已经准备好的, 是形容词
    • 对于一个Connection来说, PreparedStatement创建出来只能执行传递的一条SQL


再看一下 Statement 对象的函数

Statement 对象的函数都要传一下SQL进去, 他就是个SQL执行器,
如图,statement对象是通过数据库创建出来后, 就是一个sql执行器,一个statement可以执行多个SQL, 不支持参数预定义,可以用于执行固定的sql
image.png
为什么说 Statement 不能防止SQL注入? 比如我们要调用execute函数, 要给他传一个sql字符串进去,那么这整个字符串都一个可修改的变量, 假设这个字符串是业务动态拼接传递进来的, 想搞坏事的人给接口传了写奇奇怪怪的参数


SQL注入的例子

就是个例子别当真,我也没遇到过注入问题,都是理论,明白注入的道理就好

把main函数当成Web Ajax的入参解析;
image.png
SQL注入者成功拿到了目的数据, 顺手把你表删了,一点都不注重可持续发展;
image.png
而preparedStatement 在创建时就必须要为其赋值一个sql, 可以为其设置预定义值,所以preparedStatement一个对象只能服务一条sql,
你想想SQL的模板都定义好了,就是靠程序传些参数进去, 具体看下面描述;



为什么说PreparedStatement有防止SQL注入的功能

首先要理解什么是SQL注入, SQL注入的方式具体可以百度; 我这边白话一点的说, SQL注入就是给SQL拼字符串参数时加一些固定的SQL语法,比如注释--,比如一些奇奇怪怪的SQL函数,比如关键字, 但是可以保证的是SQL注入能修改的点只有参数, 而PreparedStatement支持预定义参数, 这时候就可以给参数变量做校验,比如必须是Int类型,不是就报错, PreparedStatement对象设置参数是可以选择参数类型,而SQL注入一般都是字符类型;**
image.png
**如果非要抓着SQL注入这一点,**PreparedStatement的确比Statement好的,但你说Statement就不能我先校验一下SQL吗, 当然也可以,仁者见仁;



PreparedStatement还有什么好处吗?

就非要用这些核心的对象支持操作SQL吗1. 设计角度 :从逻辑上讲,Java的Connection对象对应 代码和DB之间的一条连接, 数据库执行一个链接执行SQL那是串行的, 并行只会发生在多个Connection之间; 你看Statement对象,假如就有人喜欢 create多个Statement, 然后Java的Thread一起跑呢, 其实这样也没关系, 因为Statement正在执行 execute (新增,编辑)操作的时候都给加了synchronized关键字,但就是怪怪的, 就好像哥几个去洗澡, 交钱的时候说可以一起玩, 到房间了又说只能一个个来; 怪哉

  1. 开发角度: 从基础的抽象原则, OO思想, 代码可维护性角度上来讲, 在代码里写字符串SQL已经很不人道了, 难道连不同类型的参数都要搞成String传进去吗, 非要这样为什么不试试存储过程呢? 效率比Java高,能省大量连接数, 连数据处理都可以让数据库自己去做; 所以PreparedStatement有个好处就是提供了参数类型API

  2. 支持DB的预编译

具体看这篇, 人家已经写的很好了, 这里不复述 https://www.cnblogs.com/micrari/p/7112781.html





总结

静态SQL可用Statement
复杂的动态的用PreparedStatement肯定不会错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值