一、jpa批量新增數(shù)據(jù)
saveAll()方法不可取采呐,看下源碼就知道其原理是 for 循環(huán)每一條數(shù)據(jù),然后先select一次搁骑,如果數(shù)據(jù)庫存在斧吐,則update。如果不存在仲器,則insert煤率。
相關(guān)源碼如下:
@Transactional
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "Entities must not be null!");
List<S> result = new ArrayList<S>();
for (S entity : entities) {
result.add(save(entity));
}
return result;
}
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
解決方法:只基于jpa作優(yōu)化,jdbc乏冀、mybatis不在討論范圍之內(nèi)(原生SQL大法好)
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void addBatch(List<ProjectApplyDO> list) {
for (ProjectApplyDO projectApplyDO : list) {
entityManager.persist(projectApplyDO);
}
entityManager.flush();
entityManager.clear();
}
二蝶糯、jpa分頁查詢
非原生SQL(條件包含字符串、日期類型)例子如下:
public Page<ProjectApplyDO> findAll(ProjectApplyDO projectApplyDO, PageDO pageDO) {
Sort sort = new Sort(Sort.Direction.DESC, "id");
// 分頁從0開始
Pageable pageable = PageRequest.of(pageDO.getCurrent() - 1, pageDO.getSize(), sort);
return projectApplyDao.findAll((Specification<ProjectApplyDO>) (root, query, builder) -> {
Predicate predicate = builder.conjunction();
List<Expression<Boolean>> list = predicate.getExpressions();
if (projectApplyDO.getUuid() != null) {
list.add(builder.equal(root.get("uuid"), projectApplyDO.getUuid()));
}
if (projectApplyDO.getProjectName() != null) {
list.add(builder.like(root.get("projectName"), "%" + projectApplyDO.getProjectName() + "%"));
}
if (projectApplyDO.getApplyStartDate() != null) {
list.add(builder.greaterThan(root.get("applyStartDate"), projectApplyDO.getApplyStartDate()));
}
if (projectApplyDO.getApplyEndDate() != null) {
list.add(builder.lessThan(root.get("applyEndDate"), projectApplyDO.getApplyEndDate()));
}
return predicate;
}, pageable);
}
三辆沦、原生SQL增刪改查
- 使用 EntityManager 實現(xiàn)增刪改查昼捍,應(yīng)該是學(xué)習(xí)成本最低的一種方式。
@PersistenceContext
private EntityManager entityManager;
public List<ProjectApplyDO> findAll(ProjectApplyDO projectApplyDO, PageDO pageDO) {
// 字符串任意拼接
String sql = ...
Query sql = entityManager.createNativeQuery(sql, ProjectApplyDO.class);
return sql.getResultList();
}
- 使用注解 @Query
2.1众辨、參數(shù)為 Entity 對象端三,語法比較古怪
@Modifying
@Query(value = "insert into cms_system_notice (content, start_date, end_date, create_user) values (:#{#notice.content}, :#{#notice.startDate}, :#{#notice.endDate}, :#{#notice.createUser})", nativeQuery = true)
void insert(@Param("notice") SystemNoticeDO systemNoticeDO);
2.2、參數(shù)為基本類型
@Modifying
@Query(value = "update cms_system_notice set status = :status where id = :id", nativeQuery = true)
void updateStatus(@Param("id") int id, @Param("status") int status);
用mybatis鹃彻,基于注解開發(fā)郊闯,也沒什么配置,只需要會原生SQL蛛株,就可以上手了团赁。
相比之下,jpa麻煩多了谨履,還涉及一些SQL優(yōu)化欢摄,控制臺打印SQL因為表名別名原因,也不簡潔美觀笋粟。