Play Framework 大批量插入数据


 

有时候我们要一次插入大量数据到数据库中,比如10000条。但是,如果直接用 Play 框架常用的 Model.save() 方法循环插入,那么相当于操作了10000次数据库,执行会非常慢!例如下面的代码:

package util;

import models.finance.BalanceRecordModel;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 */
public class BalanceUtil {
    // 按月份对账
    public static Boolean excute(String period) throws Exception {
        // 保存数据
        for (int i = 0; i < 10000; i++) {
            BalanceRecordModel record = new BalanceRecordModel();
            record.balanceAt = new Date();
            record.save();
        }

        return true;
    }
}

为了极大的减少数据库的访问,我们使用 JPA.em().flush()JPA.em().clear()方法控制数据库的访问,比如每500条数据插入到数据库一次,这样10000条数据库只用访问 20 次数据库。代码参考如下:

package util;

import models.finance.BalanceRecordModel;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 */
public class BalanceUtil {
    // 按月份对账
    public static Boolean excute(String period) throws Exception {
        // 保存数据
        for (int i = 0; i < 10000; i++) {
            BalanceRecordModel record = new BalanceRecordModel();
            record.balanceAt = new Date();
            record.save();
            // 每500条提交到数据库一次
            if (i % 500 == 0) {
                Logger.info(">>>>>>>>>>>>>>>>>>>>>>>flush");
                JPA.em().flush();
                JPA.em().clear();
            }
        }

        return true;
    }
}

说明:

play 会自动管理事务。当 http 请求到达,play 就会为每个 http 请求启动一个事务。当 http response 发送的时候,就会把事务提交。如果代码抛出异常,事务将会自动回滚。所有不需要使用JPA.em().getTransaction().begin()JPA.em().getTransaction().commit()方法来手动控制事务。也不用使用@NoTransaction注释来关闭事务,保持默认的事务机制就可以了。


前一篇:
后一篇:

评论

caca 11月09日 18:03  回复

可以用wireshark抓包看下,只是批量commit,并非所说的”这样10000条数据库只用访问 20 次数据库“

发表评论