【问题标题】:statement.executeBatch() vs statement.updateQuery() when there is only one query to be executedstatement.executeBatch() vs statement.updateQuery() 当只有一个查询要执行时
【发布时间】:2014-12-18 08:17:55
【问题描述】:

好的,我知道批处理允许将相关的 SQL 语句分组到一个批处理中,并通过一次调用数据库来提交它们。一次向数据库发送多个 SQL 语句时,可以减少通信开销,从而提高性能。在这种特殊情况下(参见下面的代码),我认为批处理并不是唯一的目的。原因 stmt.executeBatch() 在添加批处理后立即被调用(?)stmt.executeUpdate() 不会做同样的事情吗?

public void tableChanged(TableModelEvent e) {
    int row = e.getFirstRow();
    int col = e.getColumn();
    model = (MyTableModel) e.getSource();
    String stulpPav = model.getColumnName(col);
    Object data = model.getValueAt(row, col);
    Object studId = model.getValueAt(row, 0);
    System.out.println("tableChanded works");
    try {
        new ImportData(stulpPav, data, studId);
        bottomLabel.setText(textForLabel());
    } catch (ClassNotFoundException e1) {
        e1.printStackTrace();
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
}
public class ImportData {    

    public ImportData(String a, Object b, Object c)
            throws ClassNotFoundException, SQLException {
        Statement stmt = null;
        try {
            connection = TableWithBottomLine.getConnection();
            String stulpPav = a;
            String duom = b.toString();
            String studId = c.toString();
            System.out.println(duom);
            connection.setAutoCommit(false);
            stmt = connection.createStatement();
            stmt.addBatch("update finance.fin set " + stulpPav + " = " + duom
                    + " where ID = " + studId + ";");
            stmt.executeBatch();
            connection.commit();
        } catch (BatchUpdateException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (stmt != null)
                stmt.close();
            connection.setAutoCommit(true);
            System.out.println("Data was imported to database");
        }
    }   
} 

【问题讨论】:

    标签: java mysql sql connection


    【解决方案1】:

    在这种情况下,使用批处理完全没有优势。它甚至可能会比直接 executeUpdate 引入额外的开销(但这取决于驱动程序和数据库)。

    但是,不要假设批处理对所有 JDBC 驱动程序都有优势。我没有查看 MySQL 的细节,但我知道有 JDBC 驱动程序,其中内部批处理是批处理中每个语句的正常执行。

    但是,您问题中的代码有一个更大的问题:它容易受到 SQL 注入的攻击。

    【讨论】:

    • 感谢您的洞察力。我可能应该使用准备好的语句来避免 SQL 注入,对吧?
    • @Paul 是的,使用准备好的语句将解决部分 SQL 注入漏洞。但是,您允许指定列名的事实是进一步的注入风险,无法通过准备好的语句解决。
    • 列名别名能解决问题吗?如果没有,请问正确的方法是什么?
    • @Paul 我看不出列别名如何帮助您处理更新语句。您可能想发布一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2013-04-06
    • 2014-02-27
    相关资源
    最近更新 更多