JPA使用中應注意的地方
- 寫在前面
- 一、事務處理
- 二、儲存和批量儲存
- 三、SQL日志列印問題
寫在前面
一、事務處理
@Transactional,這個注解,想要關聯事務處理,要特别注意異常處理
二、儲存和批量儲存
關于JPA中save,saveAndFlush和saveAll的差別,
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
@Transactional
public <S extends T> S saveAndFlush(S entity) {
S result = save(entity);
flush();
return result;
}
@Transactional
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
List<S> result = new ArrayList<S>();
for (S entity : entities) {
result.add(save(entity));
}
return result;
}
// 測試,耗時約 130-170 s
@GetMapping("/batch-add")
public ResultBean batchAdd() {
LocalDateTime start = LocalDateTime.now();
for (int i = 60000; i < 61000; i++) {
UserInfo u = new UserInfo();
u.setUserName("name" + i);
u.setUserCode("code" + i);
userRepository.save(u);
}
LocalDateTime end = LocalDateTime.now();
return ResultBean.ok(ChronoUnit.SECONDS.between(start,end));
}
// 測試,耗時約 1 s
@GetMapping("/batch-all")
public ResultBean batchAllAdd() {
ArrayList<UserInfo> list = Lists.newArrayList();
LocalDateTime start = LocalDateTime.now();
for (int i = 61000; i < 62000; i++) {
UserInfo u = new UserInfo();
u.setUserName("name" + i);
u.setUserCode("code" + i);
list.add(u);
}
userRepository.saveAll(list);
LocalDateTime end = LocalDateTime.now();
return ResultBean.ok(ChronoUnit.SECONDS.between(start, end));
}