Prepared Statement是一个稍微强大的Statement语句版本,并且应该始终至少与Statement一样快速和容易处理.
准备好的声明可以参数化
大多数关系数据库分四步处理JDBC/SQL查询:
对于发送到数据库的每个SQL查询,语句将始终执行上述四个步骤.准备语句在上面的执行过程中预先执行步骤(1) - (3).因此,在创建Prepared Statement时,会立即执行一些预优化.其效果是减少执行时数据库引擎的负载.
现在我的问题是 - "使用预备声明还有其他优势吗?"
Bal*_*usC 188
SQL语句的预编译和数据库端缓存可以提高整体执行速度,并能够批量重用相同的SQL语句.
通过内置转义引号和其他特殊字符自动防止SQL注入 攻击.请注意,这要求您使用任何PreparedStatement
setXxx()
方法来设置值
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
preparedStatement.setString(1, person.getName());
preparedStatement.setString(2, person.getEmail());
preparedStatement.setTimestamp(3, new Timestamp(person.getBirthdate().getTime()));
preparedStatement.setBinaryStream(4, person.getPhoto());
preparedStatement.executeUpdate();
Run Code Online (Sandbox Code Playgroud)
因此不要通过字符串连接来内联SQL字符串中的值.
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'");
preparedStatement.executeUpdate();
Run Code Online (Sandbox Code Playgroud)简化非标准的Java对象的设定在SQL字符串,例如Date
,Time
,Timestamp
,BigDecimal
,InputStream
(Blob
)和Reader
(Clob
).在大多数类型中,你不能toString()
像在简单中那样"只"做一个Statement
.您甚至可以将其全部重构为PreparedStatement#setObject()
在循环内使用,如下面的实用方法所示:
public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
for (int i = 0; i < values.length; i++) {
preparedStatement.setObject(i + 1, values[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用如下:
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
setValues(preparedStatement, person.getName(), person.getEmail(), new Timestamp(person.getBirthdate().getTime()), person.getPhoto());
preparedStatement.executeUpdate();
Run Code Online (Sandbox Code Playgroud)Gle*_*est 47
They are pre-compiled (once), so faster for repeated execution of dynamic SQL (where parameters change)
Database statement caching boosts DB execution performance
Databases store caches of execution plans for previously executed statements. This allows the database engine to reuse the plans for statements that have been executed previously. Because PreparedStatement uses parameters, each time it is executed it appears as the same SQL, the database can reuse the previous access plan, reducing processing. Statements "inline" the parameters into the SQL string and so do not appear as the same SQL to the DB, preventing cache usage.
Binary communications protocol means less bandwidth and faster comms calls to DB server
Prepared statements are normally executed through a non-SQL binary protocol. This means that there is less data in the packets, so communications to the server is faster. As a rule of thumb network operations are an order of magnitude faster than disk operations which are an order of magnitude faster than in-memory CPU oeprations. Hence, any reduction in amount of data sent over the network will have a good effect on overall performance.
They protect against SQL injection, by escaping text for all the parameter values provided.
They provide stronger separation between the query code and the parameter values (compared to concatenated SQL strings), boosting readability and helping code maintainers quickly understand inputs and outputs of the query.
In java, can call getMetadata() and getParameterMetadata() to reflect on the result set fields and the parameter fields, respectively
In java, intelligently accepts java objects as parameter types via setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp - it converts into JDBC type format that is comprehendible to DB (not just toString() format).
In java, accepts SQL ARRAYs, as parameter type via setArray method
In java, accepts CLOBs, BLOBs, OutputStreams and Readers as parameter "feeds" via setClob/setNClob, setBlob, setBinaryStream, setCharacterStream/setAsciiStream/setNCharacterStream methods, respectively
In java, allows DB-specific values to be set for SQL DATALINK, SQL ROWID, SQL XML, and NULL via setURL, setRowId, setSQLXML ans setNull methods
In java, inherits all methods from Statement. It inherits the addBatch method, and additionally allows a set of parameter values to be added to match the set of batched SQL commands via addBatch method.
In java, a special type of PreparedStatement (the subclass CallableStatement) allows stored procedures to be executed - supporting high performance, encapsulation, procedural programming and SQL, DB administration/maintenance/tweaking of logic, and use of proprietary DB logic & features
duf*_*ymo 37
PreparedStatement
防止SQL注入攻击是一种非常好的防御(但不是万无一失).绑定参数值是防止"小Bobby表"进行不必要访问的好方法.
Pan*_*kaj 29
PreparedStatement对Statement的一些好处是:
有关SQL注入问题的更多信息,请访问http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
mhs*_*ams 13
没什么可补充的,
1 - 如果要在循环中执行查询(超过1次),由于您提到的优化,准备好的语句可以更快.
2 - 参数化查询是避免SQL注入的好方法,只能在PreparedStatement中使用.
归档时间: |
|
查看次数: |
239648 次 |
最近记录: |