2017-02-15 123 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); 

    } 
}); 

希望這有助於。