0

我正在使用以下代码

con.setAutoCommit(false);

for(int i=0;i<requestBody.size();i++)
{
    bulk_Update_Qry = new StringBuffer();

    if (requestBody.getUserDetails().get(i).getFirstName() != null) 
        dbutil.setField(bulk_Update_Qry, "FIRST_NAME",requestBody.getUserDetails().get(i).getFirstName());
    if (requestBody.getUserDetails().get(i).getLastName() != null)
        dbutil.setField(bulk_Update_Qry, "LAST_NAME",requestBody.getUserDetails().get(i).getLastName());
    if (requestBody.getUserDetails().get(i).getPhone() != null)
        dbutil.setField(bulk_Update_Qry, "PHONE",requestBody.getUserDetails().get(i).getPhone() );
    if (requestBody.getUserDetails().get(i).getEmail() != null)
        dbutil.setField(bulk_Update_Qry, "EMAIL",requestBody.getUserDetails().get(i).getEmail());
    if (requestBody.getUserDetails().get(i).getAddress()!= null)
        dbutil.setField(bulk_Update_Qry, "ADDRESS",requestBody.getUserDetails().get(i).getAddress());
    if (requestBody.getUserDetails().get(i).getZip() != null)
        dbutil.setField(bulk_Update_Qry, "ZIP",requestBody.getUserDetails().get(i).getZip() );
    if (requestBody.getUserDetails().get(i).getCity() != null)
        dbutil.setField(bulk_Update_Qry, "CITY",requestBody.getUserDetails().get(i).getCity() );
    if (requestBody.getUserDetails().get(i).getState() != null)
        dbutil.setField(bulk_Update_Qry, "STATE",requestBody.getUserDetails().get(i).getState());
    if (requestBody.getUserDetails().get(i).getCountry() != null)
        dbutil.setField(bulk_Update_Qry, "COUNTRY",requestBody.getUserDetails().get(i).getCountry());

    System.out.println("UPDATE CINR_USER SET " + bulk_Update_Qry + " WHERE ID = \'" + requestBody.getUserDetails().get(i).getId() + "\'");
    ps = con.prepareStatement("UPDATE CINR_USER SET " + bulk_Update_Qry + " WHERE ID = \'" + requestBody.getUserDetails().get(i).getId() + "\'");

    ps.addBatch();
}
ps.executeBatch();
con.commit();

这是一个动态更新查询。

setField是我定义的一个函数,用于验证它是否存在于请求中。

我面临的问题

如果有 5 个更新查询,则只执行第 5 个查询。我不确定前四个查询发生了什么。

我也买不起

ps = con.prepareStatement(.....)

在 for 循环之外,因为我正在使用动态更新查询。

谁能澄清我做错了什么?

4

2 回答 2

2

在每个循环中,您都在创建一个新PreparedStatement对象,并且批处理是每个语句对象。换句话说,每个循环都丢弃前一个循环的批处理,最后你有一个准备好的语句,其中一个批处理只包含一个语句,所以你只执行在循环的最终运行中定义的语句。

有几种方法可以解决这个问题:

  1. 使用Statement在循环之外创建的普通对象。
    这会起作用,因为您实际上并没有使用准备好的语句的主要功能,但这也是不安全的。您当前构建语句的方式使您对 SQL 注入敞开大门。
  2. 不要尝试使用批处理,而只是在循环内执行语句。
    但在此之前,您需要齐心协力并正确参数化您的查询。
  3. 在循环之前使用正确参数化的查询定义多个准备好的语句,并在正确的语句中添加一个批处理,在循环之后执行所有这些查询。
于 2017-09-30T14:49:34.943 回答
1

每次调用时,prepareStatement您都会创建一个新PreparedStatement对象,这显然具有清除该PreparedStatement对象前一个实例的批处理的效果。因此,当您最终调用executeBatch它时,它仅包含循环最后一次迭代的单个条目。

PreparedStatement因此,如果您需要为每次迭代执行不同的操作,则需要调用executeUpdate而不是addBatch(并省略executeBatch调用)。由于您(ab)使用PreparedStatement来执行动态 SQL,您可以使用简单的Statement和 call addBatch(sql),但强烈建议不要使用动态 SQL,因为它会使您的代码面临 SQL 注入漏洞。

于 2017-09-30T14:48:41.017 回答