首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >语句与PreparedStatement的区别

语句与PreparedStatement的区别
EN

Stack Overflow用户
提问于 2010-07-17 11:16:00
回答 14查看 283.8K关注 0票数 244

准备好的语句是语句的一个稍微更强大的版本,并且应该始终与语句一样快速和容易处理。

准备好的报表可以参数化。

大多数关系数据库分四个步骤处理JDBC / SQL查询:

  1. 解析传入的SQL查询
  2. 编译SQL查询
  3. 计划/优化数据采集路径
  4. 执行优化的查询/获取和返回数据

对于发送到数据库的每个SQL查询,一条语句将始终执行上述四个步骤。准备好的语句预执行上述执行过程中的步骤(1) - (3)。因此,在创建准备好的语句时,会立即执行一些预优化。其效果是在执行时减少数据库引擎的负载。

现在我的问题是:

“使用预先准备的声明还有其他好处吗?”

EN

回答 14

Stack Overflow用户

发布于 2010-07-17 21:37:07

PreparedStatement的优势

  • 预编译和SQL语句的DB端缓存将导致总体上更快的执行以及在批次中重用相同的SQL语句的能力。
  • 自动防止SQL注入 攻击的内置转义引号和其他特殊字符。请注意,这需要使用任何PreparedStatement setXxx()方法来设置值。 preparedStatement =connection.prepareStatement(“插入个人(姓名、电子邮件、生日、照片)值(?、?)");preparedStatement.setString(1,person.getName();preparedStatement.setString(2,person.getEmail());preparedStatement.setTimestamp(3,新时间戳(person.getBirthdate().getTime();preparedStatement.setBinaryStream(4,person.getPhoto();preparedStatement.executeUpdate(); 因此,不通过字符串连接来内联字符串中的值。 preparedStatement =connection.prepareStatement(“插入Person (姓名、电子邮件)值”('“+ person.getName() +”“,”+ person.getEmail() +“);preparedStatement.executeUpdate();
  • 在SQL字符串中简化了非标准Java对象的设置,例如DateTimeTimestampBigDecimalInputStream (Blob)和Reader (Clob)。在大多数这些类型中,您不能像在简单的toString()中那样“只做”一个Statement。您甚至可以将其重构为在循环中使用PreparedStatement#setObject(),如下面的实用程序方法所示: 公共静态setValues(PreparedStatement preparedStatement,Object.)抛出SQLException { for (int i= 0;i< values.length;i++) { preparedStatement.setObject(i + 1,value);} 如下所示: preparedStatement =connection.prepareStatement(“插入个人(姓名、电子邮件、生日、照片)值(?,?)");setValues(preparedStatement,person.getName(),person.getEmail(),新时间戳(person.getBirthdate().getTime(),person.getPhoto());preparedStatement.executeUpdate();
票数 214
EN

Stack Overflow用户

发布于 2012-11-06 05:46:13

  1. 它们是预编译的(一次),因此对于动态SQL的重复执行(参数更改)来说,速度更快。
  2. 数据库语句缓存提高了DB执行性能。 数据库存储以前执行的语句的执行计划的缓存。这允许数据库引擎对先前执行的语句重用计划。因为PreparedStatement使用参数,所以每次执行它时,数据库都可以重用以前的访问计划,从而减少了处理。语句将参数“内联”到SQL字符串中,因此在DB中不显示为相同的SQL,从而防止了缓存的使用。
  3. 二进制通信协议意味着更少的带宽和更快的对DB服务器的通信调用。 准备好的语句通常通过非SQL二进制协议执行。这意味着数据包中的数据较少,因此与服务器的通信更快。作为经验法则,网络操作比磁盘操作慢一个数量级,后者比内存中CPU操作慢一个数量级。因此,通过网络发送的数据量的任何减少都将对总体性能产生良好的影响。
  4. 它们通过对所提供的所有参数值转义文本来防止SQL注入。
  5. 它们在查询代码和参数值之间提供了更强的分离(与连接的SQL字符串相比),提高了可读性,并帮助代码维护人员快速了解查询的输入和输出。
  6. 在java中,可以分别调用getMetadata()和getParameterMetadata()来反映结果集字段和参数字段
  7. 在java中,通过setObject、setBoolean、setByte、setDate、setDouble、setDouble、setFloat、setInt、setLong、setShort、setTime、setTimestamp智能地接受java对象作为参数类型--它将转换为JDBC类型格式,这种格式可以理解为DB (不仅仅是toString()格式)。
  8. 在java中,通过setArray方法接受SQL数组作为参数类型。
  9. 在java中,通过setClob/setNClob、setCharacterStream/setAsciiStream/setNCharacterStream、setBinaryStream和setBinaryStream方法分别接受CLOBs、BLOB、OutputStreams和读取器作为参数“feed”。
  10. 在java中,允许通过setURL、setRowId、setSQLXML和setNull方法为SQL DATALINK、SQL ROWID、SQL XML和NULL设置特定于数据库的值。
  11. 在java中,继承语句中的所有方法。它继承了addBatch方法,并允许添加一组参数值,以便通过addBatch方法匹配批处理的SQL命令集。
  12. 在java中,一种特殊类型的PreparedStatement (子类CallableStatement)允许执行存储过程--支持高性能、封装、过程编程和SQL、DB管理/维护/逻辑调整,以及使用专用DB逻辑和特性。
票数 56
EN

Stack Overflow用户

发布于 2010-07-17 12:05:09

PreparedStatement是预防SQL注入攻击的一个很好的防御(但不是万无一失)。绑定参数值是防止“小波比桌”进行不必要访问的好方法。

票数 39
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3271249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档