语句和PreparedStatement之间的java差异
准备好的语句是语句的一个稍微更强大的版本,并且应该始终至少和语句一样快速和容易处理
准备好的语句可以参数化
大多数关系数据库通过四个步骤处理JDBC/SQL查询:
- 解析传入的SQL查询
- 编译SQL查询
- 规划/优化数据采集路径
- 执行优化的查询/获取和返回数据
对于发送到数据库的每个SQL查询,语句将始终执行上述四个步骤。准备好的语句预执行上述执行过程中的步骤(1)-(3)。因此,在创建准备好的语句时,会立即执行一些预优化。其效果是在执行时减轻数据库引擎的负载
现在我的问题是:
“使用预处理语句还有其他好处吗?”
# 1 楼答案
它们是预编译的(一次),因此重复执行动态SQL(参数更改时)的速度更快。
数据库语句缓存提高数据库执行性能
数据库为以前执行的语句存储执行计划的缓存。这使得数据库引擎可以重用以前执行过的语句的计划。因为PreparedStatement使用参数,所以每次执行时都显示为相同的SQL,数据库可以重用以前的访问计划,从而减少处理。语句将参数“内联”到SQL字符串中,因此在DB中不会显示为相同的SQL,从而阻止缓存的使用
二进制通信协议意味着更少的带宽和更快的对DB服务器的通信调用
准备好的语句通常通过非SQL二进制协议执行。这意味着数据包中的数据更少,因此与服务器的通信速度更快。根据经验,网络操作比磁盘操作慢一个数量级,磁盘操作比内存CPU操作慢一个数量级。因此,通过网络发送的数据量的任何减少都将对整体性能产生良好的影响
它们通过为提供的所有参数值转义文本来防止SQL注入
它们在查询代码和参数值之间提供了更强的分离(与连接的SQL字符串相比),提高了可读性,并帮助代码维护人员快速理解查询的输入和输出
在java中,可以调用getMetadata()和getParameterMetadata()分别反映结果集字段和参数字段
在java中,通过setObject、setBoolean、setByte、setDate、setDouble、setDouble、setFloat、setInt、setLong、setShort、setTime、setTimestamp智能地接受java对象作为参数类型-它转换为数据库可理解的JDBC类型格式(不仅仅是toString()格式)
在java中,通过setArray方法接受SQL数组作为参数类型
在java中,分别通过setClob/setNClob、setBlob、setBinaryStream、setCharacterStream/setascistream/setNCharacterStream方法接受clob、blob、OutputStreams和reader作为参数“feed”
在java中,允许通过setURL、setRowId、setQLXML和setNull方法为SQL数据链接、SQL ROWID、SQL XML和NULL设置特定于数据库的值
在java中,从语句继承所有方法。它继承了addBatch方法,并且还允许添加一组参数值,以通过addBatch方法匹配批处理SQL命令集
在java中,一种特殊类型的PreparedStatement(CallableStatement子类)允许执行存储过程—支持高性能、封装、过程编程和SQL、DB管理/维护/调整逻辑以及使用专有的DB逻辑&;功能
# 2 楼答案
PreparedStatement
是防止SQL injection attacks的一种很好的防御(但不是万无一失的)。绑定参数值是防止"little Bobby Tables"进行不必要访问的一种好方法# 3 楼答案
没什么可补充的
1-如果您想在循环中执行查询(超过1次),由于您提到的优化,prepared语句可以更快
参数化查询是避免SQL注入的好方法。参数化查询仅在PreparedStatement中可用
# 4 楼答案
与报表相比,编制报表的一些好处是:
在http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example上阅读有关SQL注入问题的更多信息
# 5 楼答案
语句是静态的,而准备好的语句是动态的
语句适用于DDL,准备语句适用于DML
语句速度较慢,而准备好的语句速度较快
more differences(存档)
# 6 楼答案
a^{} 的优点:
SQL语句的预编译和DB端缓存导致总体执行速度加快,并且能够在batches中重用相同的SQL语句
通过引号和其他特殊字符的内置转义自动防止SQL injectionattacks。请注意,这需要使用任何}方法来设置值
PreparedStatement
{因此,不逐个串接SQL字符串中的值
简化SQL字符串中非标准Java对象的设置,例如^{} 、^{} 、^{} 、^{} 、^{} (^{} )和^{} (^{} )。在大多数类型上,您不能像在简单的} 对其进行重构,如下面的实用程序方法所示:
Statement
中那样“仅仅”执行toString()
。您甚至可以在循环中使用^{可按如下方式使用: