Jpa中Specification的求和sum不生效原理分析

 更新时间:2023年08月17日 11:40:40   作者:虚惊一百场  
这篇文章主要为大家介绍了Jpa中Specification的求和sum不生效原理示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

秋天的北京一如既往的没太阳,分不清天上是云是雾或者又是什么奇奇怪怪的东西,建筑物不分黑白的证明着自己的轮廓。雾蒙蒙的天一眼望不到边,就像我需要用到Spring Data Jpa 实现一个特别小的SQL,怎么写都看不到我想要的效果一样。

简单的统计

想实现的SQL十分简单,就是一个简单的统计:

SELECT
    activity_code,
    activity_name,
    sum(contact_user_nums),
    conversion_step_code,
    conversion_step
FROM
    epm_estimate_main
WHERE
    activity_code ='1'
GROUP BY
    conversion_step_code
ORDER BY
    contact_user_nums DESC;

jpa实现方式

由于一些条条框框的原因,最终选择用jpa的这种实现方式,想到这个玩意五分钟写完就能回家玩游戏,于是上来就写:

但是查询出来的结果却不是很好看:第一,我没有拿到想要的求和;第二,查询出来的结果集包括所有字段;
好在分组和排序都按照预期的想法实现了。

方法

首先去B某搜索引擎上找,找来找去,大家的方法无非四种:

  • 第一种:去XXX的JPA, MyBatis真香;
  • 第二种:实在不行用JPQL;
  • 第三种:自己创建CriteriaBuilder,CriteriaQuery及Root;
  • 第四种:不知道怎么写,等大腿。

国内搜完,于是又去G某引擎上翻翻,老外似乎问的比较具体,但都没找到我想要的答案(散装的四级还是吃力);

翻看了一些网上的问题与解答,貌似出现了一个规律,用findAll方法实现Specification接口的文章似乎都有这个问题,而使用EntityManager自己来实现的小伙伴都不怎么关注。

findAll实现

赤裸裸的歧视,下定决心就要用这个findAll实现一把。

窗外的天色越来越暗,但是我觉得这么简单的一个查询居然浪费了我开黑的时间,不由得开始怀疑自己。不管我怎么对CriteriaQuery.multiselect操作,查询出来得结果集都是包含所有字段,不由得开始怀疑multiselect这个方法为什么没有生效,JpaSpecificationExecutor这个接口到底什么居心?

找到这个接口的API:有两个实现类(其中QuerydslJpaRepository已显示过期)

剩下的这个实现类SimpleJpaRepository中找到对应的findAll方法,它调用了本类中的其他方法,一路向下找,最终在方法调用的末端,找到了其中的猫腻:

我在multiselect方法中的所有定义都被 query.select(root) 覆盖掉了!

天色已晚,华灯初上,最后本来想重写一下这个方法,但撇了一眼楼下的公交站,广告牌的背景似乎有点过年的味道。

Spring Boot自动注册了EntityManager

那段代码最终变成这样(Spring Boot自动注册了EntityManager):

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<EstimateDO> query = builder.createQuery(EstimateDO.class);
        Root<EstimateDO> root = query.from(EstimateDO.class);
        query
                .multiselect(
                        root.get("activityCode"),
                        root.get("activityName"),
                        builder.sum(root.get("contactUserNums").as(Long.class)).alias("contactUserNums"),
                        root.get("conversionStepCode"),
                        root.get("conversionStep")
                );
        List<Predicate> predicates = new ArrayList();
        predicates.add(
                builder.equal(root.get("activityCode").as(String.class), estimateDO.getActivityCode())
        );
        if (!StringUtils.isEmpty(estimateDO.getContactCode())) {
            predicates.add(
                    builder.equal(root.get("contactCode").as(String.class), estimateDO.getContactCode())
            );
        }
        query
                .where(predicates.toArray(new Predicate[predicates.size()]))
                .groupBy(root.get("conversionStepCode"))
                .orderBy(builder.desc(root.get("contactUserNums")));
        List<EstimateDO> list = entityManager.createQuery(query).getResultList();

我的决心一文不值。

以上就是Jpa中Specification的求和sum不生效原理分析的详细内容,更多关于Jpa Specification sum不生效的资料请关注脚本之家其它相关文章!

相关文章

  • SpringCloud之Ribbon使用示例解析

    SpringCloud之Ribbon使用示例解析

    这篇文章主要为大家介绍了SpringCloud之Ribbon使用示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • springboot 实现动态刷新配置的详细过程

    springboot 实现动态刷新配置的详细过程

    这篇文章主要介绍了springboot实现动态刷新配置,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • Java实现本地缓存的方式汇总

    Java实现本地缓存的方式汇总

    引入缓存,主要用于实现系统的高性能,高并发,这篇文章主要介绍了Java实现本地缓存的几种方式,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • 初识Spark入门

    初识Spark入门

    这篇文章主要介绍了初识Spark入门,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06
  • Java并发包线程池ThreadPoolExecutor的实现

    Java并发包线程池ThreadPoolExecutor的实现

    本文主要介绍了Java并发包线程池ThreadPoolExecutor的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • 从java反编译及字节码角度探索分析String拼接字符串效率

    从java反编译及字节码角度探索分析String拼接字符串效率

    这篇文章主要介绍了从java反编译及字节码角度探索分析String拼接字符串效率,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Mybatis中返回Map的实现

    Mybatis中返回Map的实现

    这篇文章主要介绍了Mybatis中返回Map的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 使用Spring特性实现接口多实现类的动态调用方式

    使用Spring特性实现接口多实现类的动态调用方式

    这篇文章主要介绍了使用Spring特性实现接口多实现类的动态调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java的字符串常量池StringTable详解

    Java的字符串常量池StringTable详解

    这篇文章主要介绍了Java的字符串常量池StringTable详解,JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化,为 了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,需要的朋友可以参考下
    2023-11-11
  • 详解Java目录操作与文件操作教程

    详解Java目录操作与文件操作教程

    本章具体介绍了目录操作、文件操作的基本使用方法和常用函数,图解穿插代码实现,感兴趣的朋友来看看吧
    2022-03-03

最新评论