简体   繁体   English

Native List在Jpa / hibernate + Spring中插入查询

[英]Native List Insert query in Jpa/hibernate + Spring

I want to insert a list of Objects in my db. 我想在我的数据库中插入一个对象列表。 In a special case I know that they primary key (not auto-generated) is not already there. 在特殊情况下,我知道他们的主键(不是自动生成的)不存在。 Since I need to insert a big collection, the save(Iterable<Obj> objects) is to slow. 由于我需要插入一个大集合,因此save(Iterable<Obj> objects)会变慢。

Therefore I consider using a native query. 因此,我考虑使用本机查询。 native insert query in hibernate + spring data hibernate + spring数据中的本机插入查询

In the previous answer, it does not say how to insert a collection of objects. 在上一个答案中,它没有说明如何插入对象集合。 Is this possible? 这可能吗?

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

Of course if you have a better solution overall, Its even better. 当然,如果你有一个更好的整体解决方案,它甚至更好。

I ended up implementing my own repository. 我最终实现了自己的存储库。 The performance of this is really good, 2s instead of 35s before to insert 50000 elements. 这个性能非常好,2s而不是35s之前插入50000个元素。 The problem with this code is that it does not prevent sql injections. 这段代码的问题在于它不会阻止sql注入。

I also tryed to build a query using setParameter(1, ...) but somehow JPA takes a long time to do that. 我还尝试使用setParameter(1, ...)构建一个查询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() + ")";
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM