使用Spring Data JPA的坑点记录总结

所属分类: 软件编程 / java 阅读数: 17
收藏 0 赞 0 分享

前言

Spring-data-jpa的基本介绍:JPA诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,百度百科说是JDK为了实现ORM的天下归一,目前也是在按照这个方向发展,但是还没能完全实现。在ORM框架中,Hibernate是一支很大的部队,使用很广泛,也很方便,能力也很强,同时Hibernate也是和JPA整合的比较良好,我们可以认为JPA是标准,事实上也是,JPA几乎都是接口,实现都是Hibernate在做,宏观上面看,在JPA的统一之下Hibernate很良好的运行。

最近在使用Springboot 以及Spring data jpa ,使用jpa可以让我更方便的操作数据库,但在使用中也遇到了不少的坑,下面这篇文章就来记录下,下面话不多说了,来一起看看详细的介绍吧。

场景:

动态查询,分页查询,根据传入不同的状态,分别查询不同数据表,并且在传入page对象之前用map进行VO转换。而pageable的使用地方不同影响到了分页数据的正确性,以此进行探讨。

  • pageable使用于new PageImpl<>中,且直到最后才将List -> Page
  • pageable使用于findAll()中

前提:

Page对象封于VO内,返回数据包括了分页数据

@ApiModelProperty("记录")
private Page<ActivityRecordVO> activityRecordVOList;
@ApiModelProperty("数量")
private Integer num = 0;
@ApiModelProperty("金额")
private BigDecimal totalMoney = BigDecimal.valueOf(0);

错误运用:

List<ActivityRecordVO> activityRecordVOList = new ArrayList<>();
  if (receiveSendRecordRequestVO.getSendOrReceiveType() == SendOrReceiveType.RECEIVE) {
   List<ChallengeRecord> challengeRecordList = challengeRecordDao.findByUserIdAndDeleteType(userId,
     DeleteType.FALSE);
   if (!CollectionUtils.isEmpty(challengeRecordList)) {
    activityRecordVOList = challengeRecordList.stream()
      .map(this::challengeRecordToActivityRecordVO)
      .collect(Collectors.toList());
   }
  } else if (receiveSendRecordRequestVO.getSendOrReceiveType() == SendOrReceiveType.SEND) {
   List<Activity> activityList = activityDao.findByUserIdAndDeleteType(userId, DeleteType.FALSE);
   if (!CollectionUtils.isEmpty(activityList)) {
    activityRecordVOList = activityList.stream()
      .map(this::activityTOActivityRecordVO)
      .collect(Collectors.toList());
   }
  }
activityReceiveSendRecordVO.setActivityRecordVOList(new PageImpl<>(activityRecordVOList,
     pageable, activityRecordVOList.size()));

解析:传入的pageable只在set进VO的时候,用new PageIml将List转为page对象,前端报的问题 虽然总页数、总条数均为正确,但第一页的条数是全部 ,数据异常!

正确参考做法:

采用Specifications先根据查询条件动态查询并map出相应分页对象(此块代码因需求而异),这时 findAll 传入的pageable是生效的,便会显现正确的分页信息。

代码块参考:

xxxCommonSpecUtil 是自封的specification工具类,与原生spring data jpa原生查询方法类似。

Page<ActivityRecordVO> page = new PageImpl<>(activityRecordVOList, pageable, activityRecordVOList.size());
  if (receiveSendRecordRequestVO.getSendOrReceiveType() == SendOrReceiveType.RECEIVE) {
   Specifications<ChallengeRecord> spec = Specifications.where(
     challengeCommonSpecUtil.equal("userId", userId))
     .and(challengeCommonSpecUtil.equal("deleteType", DeleteType.FALSE));
   page = challengeRecordDao.findAll(spec, pageable).map(this::challengeRecordToActivityRecordVO);
  } else if (receiveSendRecordRequestVO.getSendOrReceiveType() == SendOrReceiveType.SEND) {
   Specifications<Activity> spec = Specifications.where(
     activityCommonSpecUtil.equal("userId", userId))
     .and(activityCommonSpecUtil.equal("deleteType", DeleteType.FALSE));
   page = activityDao.findAll(spec, pageable).map(this::activityTOActivityRecordVO);
  }

注:activityReceiveSendRecordVO为封装的VO,包含了返回的Page对象

activityReceiveSendRecordVO.setActivityRecordVOList(page);

使用了这么长时间spring data jpa,觉得Specifications巨好用,也不容易出错,也是我喜欢的编码风格,而new PageImpl<>()这种简单粗暴的方法我一般都用在查询数据关联太多表的情况,在最后直接返回,更深层次的还需要再探讨!

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

Java数据类型的规则

这篇文章主要介绍了Java数据类型的规则的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring整合TimerTask实现定时任务调度

这篇文章主要介绍了Spring整合TimerTask实现定时任务调度的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

详解SpringMVC使用MultipartFile实现文件的上传

本篇文章主要介绍了SpringMVC使用MultipartFile实现文件的上传,本地的文件上传到资源服务器上,比较好的办法就是通过ftp上传。这里是结合SpringMVC+ftp的形式上传的,有兴趣的可以了解一下。
收藏 0 赞 0 分享

SpringMVC上传文件的三种实现方式

本篇文章主要介绍了SpringMVC上传文件的三种实现方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

本篇文章主要介绍了微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
收藏 0 赞 0 分享

浅析Java中的继承与组合

本文将介绍组合和继承的概念及区别,并从多方面分析在写代码时如何进行选择。文中通过示例代码介绍的很详细,有需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

利用反射获取Java类中的静态变量名及变量值的简单实例

下面小编就为大家带来一篇利用反射获取Java类中的静态变量名及变量值的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java启动线程的3种方式对比分析

这篇文章主要为大家对比分析了java启动线程的3种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SpringMVC上传和解析Excel方法

这篇文章主要介绍了SpringMVC上传和解析Excel方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

JAVA中String类与StringBuffer类的区别

这篇文章主要为大家详细介绍了JAVA中String类与StringBuffer类的区别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多