美文网首页
jpa操作数据库问题总结

jpa操作数据库问题总结

作者: 纳米君 | 来源:发表于2020-06-09 15:31 被阅读0次

一、jpa批量新增数据

saveAll()方法不可取,看下源码就知道其原理是 for 循环每一条数据,然后先select一次,如果数据库存在,则update。如果不存在,则insert。
相关源码如下:

    @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作优化,jdbc、mybatis不在讨论范围之内(原生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增删改查

  1. 使用 EntityManager 实现增删改查,应该是学习成本最低的一种方式。
    @PersistenceContext
    private EntityManager entityManager;

    public List<ProjectApplyDO> findAll(ProjectApplyDO projectApplyDO, PageDO pageDO) {
        // 字符串任意拼接
        String sql = ...
        Query sql = entityManager.createNativeQuery(sql, ProjectApplyDO.class);
        return sql.getResultList();
    }
  1. 使用注解 @Query

2.1、参数为 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、参数为基本类型

@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,基于注解开发,也没什么配置,只需要会原生SQL,就可以上手了。
相比之下,jpa麻烦多了,还涉及一些SQL优化,控制台打印SQL因为表名别名原因,也不简洁美观。

相关文章

网友评论

      本文标题:jpa操作数据库问题总结

      本文链接:https://www.haomeiwen.com/subject/ocwstktx.html