2016-10-26 7 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

私は自分のリポジトリを実装しました。このパフォーマンスは、5万個の要素を挿入する前の35秒ではなく、2秒で良いです。このコードの問題は、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() + ")"; 
    } 
} 
関連する問題