2016-10-26 44 views
4

我想在我的數據庫中插入一個對象列表。在特殊情況下,我知道他們的主鍵(不是自動生成的)還不在那裏。由於我需要插入一個大集合,所以save(Iterable<Obj> objects)會變慢。原生列表在Jpa/hibernate + Spring中插入查詢

因此我考慮使用本機查詢。 native insert query in hibernate + spring data

在上一個答案中,它沒有說如何插入一個對象集合。這可能嗎?

@Query("insert into my_table (date, feature1, feature2, quantity) VALUES <I do not know what to add here>", nativeQuery = true) 
void insert(List<Obj> objs); 

當然,如果你總體上有一個更好的解決方案,它會更好。

+1

嘗試實現彈簧數據JPA批量插入 – Kushan

回答

1

我最終實現了自己的存儲庫。這個表現非常好,2s而不是35s之前插入50000個元素。這個代碼的問題是它不能防止sql注入。

我也嘗試使用setParameter(1, ...)來構建查詢,但JPA需要很長時間才能做到這一點。

class ObjectRepositoryImpl implements DemandGroupSalesOfDayCustomRepository { 

    private static final int INSERT_BATCH_SIZE = 50000; 

    @Autowired 
    private EntityManager entityManager; 

    @Override 
    public void blindInsert(List<SomeObject> objects) { 
     partition(objects, INSERT_BATCH_SIZE).forEach(this::insertAll); 
    } 

    private void insertAll(List<SomeObject> objects) { 
     String values = objects.stream().map(this::renderSqlForObj).collect(joining(",")); 
     String insertSQL = "INSERT INTO mytable (date, feature1, feature2, quantity) VALUES "; 
     entityManager.createNativeQuery(insertSQL + values).executeUpdate(); 
     entityManager.flush(); 
     entityManager.clear(); 
    } 

    private String renderSqlForObj(Object obj) { 
     return "('" + obj.getDate() + "','" + 
      obj.getFeature1() + "','" + 
      obj.getFeature2() + "'," + 
      obj.getQuantity() + ")"; 
    } 
}