2017-02-15 85 views
2

我试图用很多测试数据填充我的数据库,所以我编写了一个CommandLineRunner来保存2k个实体。弹簧引导jpa - 生成并保存测试数据

它的工作 - 但需要永久完成(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(); 
     } 

    } 
} 
+0

我不知道为什么它花费了太多的时间,但你可以通过使用线程概念确实减少时间。由于数据已经在'generateTestData();'后面填充,所以现在在不同线程中调用每个repo save方法。 – SachinSarawgi

回答

0

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

有休眠特性,你可以定义为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(); 
     } 
    } 
} 
0

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

在致电generateTestData();致电save之前,您有数据的方法。

因此改变你的代码有点

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(); 

Thread run方法是重写使用Java 8功能,您可以在Java 7做法如下:

Thread thread1 = new Thread(new Runnable() { 

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

    } 
}); 

希望这有助于。