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

 更新时间:2017年12月14日 13:56:04   作者:Joryun刘家源  
这篇文章主要给大家总结介绍了关于使用Spring Data JPA的一些坑点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

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<>()这种简单粗暴的方法我一般都用在查询数据关联太多表的情况,在最后直接返回,更深层次的还需要再探讨!

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

相关文章

  • MapStruct表达式应用及避坑详解

    MapStruct表达式应用及避坑详解

    一不小心踩了MapStruct表达式的坑,发现了一个在官方文档上都找不到的功能,有必要记录下。MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean类型之间的映射的实现
    2022-02-02
  • Java窗口精细全方位讲解

    Java窗口精细全方位讲解

    这篇文章呢,将会系统的精细的教会铁铁们如何自己写一个完整的窗口;看完之后窗口稳拿下!!!所以呢由于详细,知识点多,可能有点长,铁铁们慢慢仔细阅读吧;文章写的还是一如既往快乐的,哈哈哈
    2021-08-08
  • Java中枚举类型的一种使用方式

    Java中枚举类型的一种使用方式

    这篇文章主要介绍了Java中枚举类型的一种使用方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Spring Security中如何获取AuthenticationManager对象

    Spring Security中如何获取AuthenticationManager对象

    有时需要使用AuthenticationManager(以下简称Manager)对象,可是这个对象不是Bean,没有直接保存在Spring的Bean库中,那么如何获取Spring Security中的这个对象呢,需要的朋友可以参考下
    2022-11-11
  • Spring MVC 中 AJAX请求并返回JSON的示例

    Spring MVC 中 AJAX请求并返回JSON的示例

    本篇文章主要介绍了Spring MVC 中 AJAX请求并返回JSON,具有一定的参考价值,有兴趣的可以了解一下。
    2017-01-01
  • Java日常练习题,每天进步一点点(40)

    Java日常练习题,每天进步一点点(40)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • Java编程实现快速排序及优化代码详解

    Java编程实现快速排序及优化代码详解

    这篇文章主要介绍了Java编程实现快速排序及优化代码详解,具有一定借鉴价值,需要的朋友可以了解下。
    2017-12-12
  • JDBC实现数据库增删改查功能

    JDBC实现数据库增删改查功能

    这篇文章主要为大家详细介绍了JDBC实现数据库增删改查功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Android应用开发之将SQLite和APK一起打包的方法

    Android应用开发之将SQLite和APK一起打包的方法

    这篇文章主要介绍了Android应用开发之将SQLite和APK一起打包的方法,文章时间较早,尽管现在开发环境已大都迁移至Android Studio上,但打包原理依然相同,需要的朋友可以参考下
    2015-08-08
  • Java Socket编程服务器响应客户端实例代码

    Java Socket编程服务器响应客户端实例代码

    这篇文章主要介绍了Java Socket编程服务器响应客户端实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2017-12-12

最新评论