spring boot jpa - 生成并保存测试数据

时间:2017-02-15 11:56:38

标签: java spring-boot spring-data-jpa

我正在尝试用大量的测试数据填充我的数据库,所以我写了一个CommandLineRunner以节省大约2k个实体。

它有效 - 但需要永远完成(5-10分钟) - 我是以错误的方式处理这个问题吗?

@Component
public class DbSeederTest implements CommandLineRunner {

    @Autowired
    FirstRepo firstRepo;
    @Autowired
    SecondRepo secondRepo;
    @Autowired
    ThirdRepo thirdRepo;

    private List<FirstEnt> firstList = new ArrayList<>();
    private List<SecondEnt> secondList = new ArrayList<>();
    private List<ThirdEnt> thirdList = new ArrayList<>();


    private void generateTestData() {
          // generate alot of entities, and add them to the Lists
    }

    @Override
    public void run(String... args) throws Exception {

        System.out.println("saving ents...");

        generateTestData();

        try {

            firstRepo.save(firstList);
            secondRepo.save(secondList);
            thirdRepo.save(thirdList);

        } catch(Exception e) {
            e.printStackTrace();
        }

    }
}

2 个答案:

答案 0 :(得分:0)

您可以尝试利用批量插入功能。

你可以将hibernate属性定义为hibernate SessionFactory的一个属性:

<property name="jdbc.batch_size">250</property>

使用此批处理设置,您应该输出如下:

insert into Table(id , name) values (1, 'na1') , (2, 'na2') ,(3, 'na3').

而不是

insert into Table(id , name) values (1, 'na1');
insert into Table(id , name) values (2, 'na2');
insert into Table(id , name) values (3, 'na3');

在您的存储库保存方法中,您将持续存在大约250个(您必须对应用程序中的最佳性能进行一些测试)实体..然后刷新会话以获得最佳性能,直到所有数据都有被保存了:

public void save(List<Item> itemList){
  for ( int i=0; i<itemList.size(); i++ ) {   
      session.save(itemList.get(i));

      if ( i % 250 == 0 ) { //250, same as the JDBC batch size
          //flush a batch of inserts and release memory:
          session.flush();
          session.clear();
      }
  }
}

答案 1 :(得分:0)

您可以减少使用线程概念所花费的时间。

在调用所有回购的save方法之前,您在调用generateTestData();后获得了数据。

所以稍微改变你的代码

Thread thread1 = new Thread(()->firstRepo.save(firstList));
Thread thread2 = new Thread(()->secondRepo.save(secondList));
Thread thread3 = new Thread(()->thirdRepo.save(thirdList));
thread1.start();
thread2.start();
thread3.start();

使用Java 8功能覆盖Thread run方法,您可以在Java 7中执行此操作,如下所示:

Thread thread1 = new Thread(new Runnable() {

    @Override
    public void run() {
        firstRepo.save(firstList);

    }
});

希望这有帮助。