2016-10-26 2 views
4

Ich möchte eine Liste von Objekten in meine Datenbank einfügen. In einem speziellen Fall weiß ich, dass der Primärschlüssel (nicht automatisch generiert) nicht schon da ist. Da ich eine große Sammlung einfügen muss, ist die save(Iterable<Obj> objects) zu langsam.Native Liste Abfrage in Jpa/Hibernate + Spring einfügen

Daher denke ich über eine native Abfrage. native insert query in hibernate + spring data

In der vorherigen Antwort wird nicht angegeben, wie eine Objektgruppe eingefügt werden soll. Ist das möglich?

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

Natürlich, wenn Sie eine bessere Lösung insgesamt haben, ist es noch besser.

+1

Versuchen Sie, den JPA-Batch-Einsatz mit Federdaten zu implementieren – Kushan

Antwort

1

Ich habe schließlich mein eigenes Repository implementiert. Die Leistung von diesem ist wirklich gut, 2s anstelle von 35s vorher, um 50000 Elemente einzufügen. Das Problem mit diesem Code ist, dass SQL-Injektionen nicht verhindert werden.

Ich habe auch versucht, eine Abfrage mit setParameter(1, ...) erstellen, aber irgendwie dauert JPA eine lange Zeit, das zu tun.

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() + ")"; 
    } 
}