我正在使用以下代码
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个更新查询,则仅执行第五个查询。我不确定前四个查询发生了什么。
我也买不起
ps = con.prepareStatement(.....)
当我使用动态更新查询时,在for循环外部。
任何人都可以澄清我做错了什么吗?
在每个循环中,您正在创建一个新的PreparedStatement
对象,并且批次为每个语句对象。换句话说,您将每个循环丢弃了上一个循环的批次,最后您有一个准备好的语句,其中只有一个包含一个语句的批次,因此您仅执行循环最终运行中定义的语句。p>有几种解决此问题的方法:
- 使用在循环外创建的普通
Statement
对象。
这会起作用,因为您实际上并没有使用准备好的语句的主要功能,但是这也不安全。您目前正在构造语句的方式使您对SQL注入开放。 - 不要尝试使用批处理,而只是在循环中执行语句。
但是在执行此操作之前,您将需要将您的行为融合在一起并正确参数化查询。 - 在循环前定义了使用正确参数化查询的多个准备好的语句,然后在正确的语句中添加一批,在循环后执行所有这些查询。
每次调用prepareStatement
时,都会创建一个新的PreparedStatement
对象,显然,该对象的效果是为PreparedStatement
对象的上一个实例清除批处理。因此,当您最终致电executeBatch
时,它仅包含循环的最后一次迭代的单个条目。
因此,如果您需要为每次迭代执行不同的PreparedStatement
,则需要调用executeUpdate
而不是addBatch
(并省略executeBatch
调用)。由于您(AB)使用PreparedStatement
执行Dynamic SQL,因此您可以使用简单的Statement
并调用addBatch(sql)
,但是使用Dynamic SQL非常灰心,因为它将您的代码打开到SQL注入漏洞。