为了账号安全,请及时绑定邮箱和手机立即绑定

多次重用PreparedStatement

多次重用PreparedStatement

精慕HU 2019-08-01 16:19:06
多次重用PreparedStatement如果将PreparedStatement与没有任何池的单个公共连接一起使用,我是否可以为每个dml / sql操作重新创建一个实例来保证预处理语句的强大功能?我的意思是:for (int i=0; i<1000; i++) {     PreparedStatement preparedStatement = connection.prepareStatement(sql);     preparedStatement.setObject(1, someValue);     preparedStatement.executeQuery();     preparedStatement.close();}代替:PreparedStatement preparedStatement = connection.prepareStatement(sql);for (int i=0; i<1000; i++) {     preparedStatement.clearParameters();     preparedStatement.setObject(1, someValue);     preparedStatement.executeQuery();}preparedStatement.close();我的问题是因为我想把这段代码放到多线程环境中,你能给我一些建议吗?谢谢
查看完整描述

2 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

第二种方式更有效,但更好的方法是批量执行它们:

public void executeBatch(List<Entity> entities) throws SQLException { 
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL);
    ) {
        for (Entity entity : entities) {
            statement.setObject(1, entity.getSomeProperty());
            // ...

            statement.addBatch();
        }

        statement.executeBatch();
    }}

但是,您依赖于JDBC驱动程序实现,您可以一次执行多少批次。例如,您可能希望每1000批次执行它们:

public void executeBatch(List<Entity> entities) throws SQLException { 
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL);
    ) {
        int i = 0;

        for (Entity entity : entities) {
            statement.setObject(1, entity.getSomeProperty());
            // ...

            statement.addBatch();
            i++;

            if (i % 1000 == 0 || i == entities.size()) {
                statement.executeBatch(); // Execute every 1000 items.
            }
        }
    }}

对于多线程环境,如果使用try-with-resources语句按照常规JDBC惯用法获取并关闭同一方法块内最短可能范围内的连接和语句,则无需担心这一点,如下所示:片段以上。

如果这些批处理是事务性的,那么您希望关闭连接的自动提交,并且只在所有批处理完成时提交事务。否则,当第一批批次成功而后者不成功时,可能会导致脏数据库。

public void executeBatch(List<Entity> entities) throws SQLException { 
    try (Connection connection = dataSource.getConnection()) {
        connection.setAutoCommit(false);

        try (PreparedStatement statement = connection.prepareStatement(SQL)) {
            // ...

            try {
                connection.commit();
            } catch (SQLException e) {
                connection.rollback();
                throw e;
            }
        }
    }}


查看完整回答
反对 回复 2019-08-01
  • 2 回答
  • 0 关注
  • 2664 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号