Pau*_*nel 7 java spring hibernate jpa
我想在我的数据库中插入一个对象列表.在特殊情况下,我知道他们的主键(不是自动生成的)不存在.因为我需要插入一个大集合,所以save(Iterable<Obj> objects)要慢.
因此,我考虑使用本机查询.hibernate + spring数据中的本机插入查询
在上一个答案中,它没有说明如何插入对象集合.这可能吗?
@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);
Run Code Online (Sandbox Code Playgroud)
当然,如果你有一个更好的整体解决方案,它甚至更好.
我最终实现了自己的存储库。这个的性能真的很好,插入50000个元素之前是2s而不是35s。这段代码的问题在于它不能阻止 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() + ")";
}
}
Run Code Online (Sandbox Code Playgroud)
小智 3
我知道这是 7 年前的事,但发布此内容只是为了以防万一有人需要使用 JdbcTemplate 的 SQL 注入安全方法,但速度与接受的答案相同。
public class MyBatchRepository {
private static final int INSERT_BATCH_SIZE = 20000;
private static final String INSERT_QUERY_BASE = "INSERT INTO table_name(column1, column2, column3) VALUES ";
private static final String INSERT_PARAM_BASE = "(?,?,?)";
private static final String DELIMITER = ",";
private JdbcTemplate jdbcTemplate;
public MyBatchRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void performBatchInsert(List<Object> objects) {
ListUtils.partition(objects, INSERT_BATCH_SIZE).forEach(this::batchInsert);
}
private void batchInsert(List<Object> objects) {
String insertQuery = buildInsertQuery(objects.size());
Object[] insertParameters = buildParameters(objects);
jdbcTemplate.update(insertQuery, insertParameters);
}
protected String buildInsertQuery(int size) {
String parameters = String.join(DELIMITER, Collections.nCopies(size, INSERT_PARAM_BASE));
return INSERT_QUERY_BASE + parameters;
}
protected Object[] buildParameters(List<Object> objects) {
return objects.stream()
.map(this::toObjectArray)
.flatMap(Stream::of)
.toArray(Object[]::new);
}
private Object[] toObjectArray(Object object) {
return new Object[]{
object.column1(),
object.column2(),
object.column3()
};
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1802 次 |
| 最近记录: |