预处理语句是Statement的一个稍微强大一点的版本,并且应该总是至少像Statement一样快速和容易处理。 预估报表可以被参数化

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

解析传入的SQL查询 编译SQL查询 规划/优化数据采集路径 执行优化的查询/获取和返回数据

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

现在我的问题是:

“使用预准备报表还有其他好处吗?”


当前回答

引用自mattjames

语句在JDBC中的使用应该100%本地化为正在使用 对于DDL (ALTER, CREATE, GRANT等),因为这些是唯一的语句 不能接受BIND变量的类型。preparedstatement或 CallableStatements应该用于所有其他类型的语句 (DML、查询)。因为这些是接受bind的语句类型 变量。 这是一个事实,一条规则,一条法律——在任何地方都使用事先准备好的陈述。 几乎不使用语句。

其他回答

准备查询或参数化查询的另一个特征:引用自本文。

该语句是数据库系统重复执行同一条SQL语句的高效特性之一。准备好的语句是模板的一种,由应用程序使用不同的参数。

语句模板准备好后发送给数据库系统,数据库系统对该模板进行解析、编译和优化,不执行即可存储。

有些参数,比如在以后的应用程序创建模板时没有传递子句,将这些参数发送给数据库系统,数据库系统使用SQL语句模板并按请求执行。

预处理语句对于SQL注入非常有用,因为应用程序可以使用不同的技术和协议来准备参数。

当数据数量不断增加,索引频繁变化时,Prepared statement可能会失败,因为在这种情况下需要一个新的查询计划。

我遵循了这个问题的所有答案,使用- Statement(但有SQL注入)将工作的遗留代码更改为使用PreparedStatement的解决方案,由于对Statement周围的语义理解不佳,代码要慢得多。addBatch(String sql) & PreparedStatement.addBatch()。

所以我在这里列出了我的情况,这样其他人就不会犯同样的错误。

我的设想是

Statement statement = connection.createStatement();

for (Object object : objectList) {
    //Create a query which would be different for each object 
    // Add this query to statement for batch using - statement.addBatch(query);
}
statement.executeBatch();

所以在上面的代码中,我有数千个不同的查询,都添加到相同的语句中,这段代码工作得更快,因为语句没有被缓存是好的&这段代码很少在应用程序中执行。

现在修复SQL注入,我把这段代码改为,

List<PreparedStatement> pStatements = new ArrayList<>();    
for (Object object : objectList) {
    //Create a query which would be different for each object 
    PreparedStatement pStatement =connection.prepareStatement(query);
    // This query can't be added to batch because its a different query so I used list. 
    //Set parameter to pStatement using object 
    pStatements.add(pStatement);
}// Object loop
// In place of statement.executeBatch(); , I had to loop around the list & execute each update separately          
for (PreparedStatement ps : pStatements) {
    ps.executeUpdate();
}

所以你看,我开始创建数千个PreparedStatement对象,然后最终不能利用批处理,因为我的场景要求-有数千个UPDATE或INSERT查询,所有这些查询碰巧是不同的。

在不降低性能的情况下修复SQL注入是强制性的,我认为在这种情况下使用PreparedStatement是不可能的。

另外,当你使用内置的批处理工具时,你必须担心只关闭一个语句,但使用这个List方法,你需要在重用之前关闭语句,重用一个PreparedStatement

语句将用于执行静态SQL语句,它不能接受输入参数。

PreparedStatement将用于多次动态执行SQL语句。它将接受输入参数。

PreparedStatement是一种非常好的防御(但不是万无一失的),可以防止SQL注入攻击。绑定参数值是防止“小Bobby表”进行不必要访问的好方法。

语句接口执行不带参数的静态SQL语句

PreparedStatement接口(扩展Statement)执行预编译的带/不带参数的SQL语句

对于重复执行有效 它是预编译的,所以更快