Java PreparedStatement、ArrayList和SQL

5
无法从ArrayList中插入新值到我的DB;我希望将所有ArrayList添加到DB列list、title、about的值,从ArrayLists pars.getListId()、getTitleId()、pars.getAboutAr()获取。
String query = "insert into test (list, title, about)" + "VALUES (?, ?, ?)";

    try {
        pars.htmlParse("hello");
        PreparedStatement preparedStmt = db.getConnection().prepareStatement(query);
        for (int i = 0; i < pars.getListId().size(); i++) {
            preparedStmt.setString(1, pars.getListId().get(i));
            preparedStmt.executeUpdate();
        }
        for (int i = 0; i < pars.getTitleId().size(); i++) {
            preparedStmt.setString(2, pars.getTitleId().get(i));
            preparedStmt.executeUpdate();
        }
        for (int i = 0; i < pars.getAboutAr().size(); i++) {
            preparedStmt.setString(3, pars.getAboutAr().get(i));
            preparedStmt.executeUpdate();
        }
        preparedStmt.execute();


        } catch (IOException e1) {
        e1.printStackTrace();

请发布您得到的堆栈跟踪。 - xaviert
所以你的pars有三个独立的列表?不只是一个数组列表?问题在于,在执行executeUpdate之前,你必须设置同一行的所有列,但如果你有三个独立的列表,如果它们的长度不相同,可能会出现问题。 - RealSkeptic
它有三个ArrayList。现在我明白它们长度不同。但这并没有解决我的问题。 - Mitchell
你有错误吗? - Abdelhak
主线程中的异常:"main" java.sql.SQLException: 未为参数2指定值 在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)处创建了SQLException 在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)处创建了SQLException 在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)处创建了SQLException 在com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2176)处填充发送数据包的准备语句 在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1993)处执行更新准备语句 在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1937)处执行更新准备语句 - Mitchell
对于列表中的每个元素,您需要执行一个单独的插入语句。现在,当您完成这项工作后,可以尝试使用批量更新。 - MadProgrammer
3个回答

1

在调用executeUpdate之前,您必须设置所有三列。

您正在执行以下操作:

        preparedStmt.setString(1, pars.getListId().get(i));
        preparedStmt.executeUpdate();

所以你只在预处理语句中设置了第一个参数,然后调用executeUpdate。但是你需要拥有全部三个参数。

你应该有一个循环,一起插入所有三个参数:

    for (int i = 0; i < pars.getListId().size(); i++) {
        preparedStmt.setString(1, pars.getListId().get(i));
        preparedStmt.setString(2, pars.getTitleId().get(i));
        preparedStmt.setString(3, pars.getAboutAr().get(i));
        preparedStmt.executeUpdate();
    }

这会在执行语句之前设置语句中的所有三列。因此,您将获得一个适当的插入语句并设置所有值。
这里的一个问题是可能发生 pars.getListId() 有5个项目,而 pars.getTitleId()pars.getAboutAr() 只有4个项目。然后,当运行上面的循环时,当 i 到达值 4 时,您将会收到一个异常,因为 pars.getTitleId() 没有值4(因为它只有4个项目)。
这可以有几种解决方案。
  1. If you know that the result of your parsing is always equal-length lists, then it's not a problem.
  2. You can insert only the values up to the shortest list. You can have a calculation like this:

    int minSize = Collections.min( Arrays.asList( pars.getListId().size(),
                                                  pars.getTitleId().size(),
                                                  pars.getAboutAr().size() ) );
    

    And then use

    for (int i = 0; i < minSize; i++) {
        preparedStmt.setString(1, pars.getListId().get(i));
        preparedStmt.setString(2, pars.getTitleId().get(i));
        preparedStmt.setString(3, pars.getAboutAr().get(i));
        preparedStmt.executeUpdate();
    }
    

    And then it will give you as many rows as the shortest list.

  3. You can go with the longest list (do max instead of min in the calculation above) and set nulls for the missing values (that is, check if the list is shorter than i requires. If so, use setNull instead of setString.

  4. Personally, I would not build pars the way you have, with three separate lists. Instead, I would create a class, perhaps named Par or whatever makes sense, which has id, title and about fields. Then I would create a single list of Par objects in my pars instead of three separate lists. And then you will not have a problem with different lengths, and the data structure will be more like what you have in the database.

0

在执行executeUpdate()之前,您需要修改您的代码以使每个参数都具有参数1、2和3。

我假设您的列表具有相等数量的条目(否则会出错)

    for (int i = 0; i < pars.getListId().size(); i++) {
        preparedStmt.setString(1, pars.getListId().get(i));
        preparedStmt.setString(2, pars.getTitleId().get(i));
        preparedStmt.setString(3, pars.getAboutAr().get(i));
        preparedStmt.executeUpdate();
    }

现在您每次插入都拥有三个设置。


0

不要尝试设置每个参数,然后执行更新操作,这会使查询处于无效状态(因为并非所有参数都被设置)。相反,你应该为每个元素设置每个参数,然后执行更新操作。

更好的解决方案是使用批量更新过程,例如:

String query = "insert into test (list, title, about)" + "VALUES (?, ?, ?)";
try (PreparedStatement ps = con.prepareStatement(query)) {
    pars.htmlParse("hello");
    for (int index = 0; index < pars.getListId().size(); index++) {
        ps.setString(1, pars.getListId().get(index));
        ps.setString(2, pars.getTitleId().get(index));
        ps.setString(3, pars.getAboutAr().get(index));
        ps.addBatch();
    }
    ps.executeBatch();
} catch (SQLException exp) {
    exp.printStackTrace();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接