• JPA或Hibernate中使用原生SQL实现分页查询、排序


    发生背景:前端展示的数据需要来自A表和D表拼接,A表和D表根据A表的主键进行关联,D表的非主键字段关联C表的主键,根据条件筛选出符合的数据,并且根据A表的主键关联B表的主键(多主键)的条件,过滤A表中不符合的数据。因为数据量较大,所以需要进行分页。
    环境:DM DatabaseJ(达梦数据库,和Oracle差不多),JPA
    使用@Query注解,使用value属性来声明查询SQL,countQuery属性取得当前查询的数量,nativeQuery属性声明为true,表示为支持当前的SQL语句为原生SQL。

    ServiceImpl:
    1 Sort sort = new Sort(Sort.Direction.DESC, "slrq");
    2 Pageable pageable = PageRequest.of(pageNum, pageSize, sort);

    Repository:
    @Query(value = "SELECT aj.ajmc AS ajmc, " +
                    "aj.ajlb_bm AS ajlbbm, " +
                    "aj.ajlb_mc AS ajlbmc, " +
                    "aj.cbdw_bm AS cbdwbm, " +
                    "aj.cbdw_mc AS cbdwmc, " +
                    "aj.cbjcg AS cbjcg, " +
                    "aj.bmsah AS bmsah, " +
                    "rz.ysdw_dwdm AS ysdwdm, " +
                    "rz.ysdw_dwmc AS ysdwmc, " +
                    "rz.ysay_aydm AS ysaydm, " +
                    "rz.ysay_aymc AS ysaymc " +
                    "FROM aj_yx_aj aj " +
                    "INNER JOIN aj_yx_slrz rz ON aj.bmsah = rz.bmsah " +
                    "INNER JOIN aj_xt_sldy dy ON rz.slbh = dy.slbm " +
                    "WHERE aj.sfsc = 'N' " +
                    "AND aj.cbdw_bm = :cbdwbm " +
                    "AND (aj.ajmc like :gjz OR aj.cbjcg like :gjz) " +
                    "AND aj.ajzt = '1' " +
                    "AND (SELECT COUNT(ry.zrrbm) FROM tyyw_gg_zrrsjls ry WHERE ry.bmsah = aj.bmsah " +
                    "AND ry.zrrlx_dm = '0009000900001' " +
                    "AND ry.sfsc = 'N') > 1 " +
                    "AND dy.sllb = '1' " +
                    "AND rz.sfsc = 'N' " +
                    "AND dy.sfsc = 'N'  ",
            countQuery = "SELECT COUNT(*) FROM " +
                    "(SELECT * FROM aj_yx_aj aj " +
                    "INNER JOIN aj_yx_slrz rz ON aj.bmsah = rz.bmsah " +
                    "INNER JOIN aj_xt_sldy dy ON rz.slbh = dy.slbm " +
                    "WHERE aj.sfsc = 'N' " +
                    "AND aj.cbdw_bm = :cbdwbm " +
                    "AND (aj.ajmc like :gjz OR aj.cbjcg like :gjz) " +
                    "AND aj.ajzt = '1' " +
                    "AND (SELECT COUNT(ry.zrrbm) FROM tyyw_gg_zrrsjls ry WHERE ry.bmsah = aj.bmsah " +
                    "AND ry.zrrlx_dm = '0009000900001' " +
                    "AND ry.sfsc = 'N') > 1 " +
                    "AND dy.sllb = '1' AND rz.sfsc = 'N' AND dy.sfsc = 'N' )", nativeQuery = true)
    //repository层的调用方法
    Page<Map> findCalb(@Param("cbdwbm") String dwbm, @Param("gjz") String gjz, Pageable pageable);

    注意:
      1、方法传入参数中的Pageable参数,在SQL并没有使用这样一个参数,但是pageable中的page参数和sort参数会在查询时自动拼接到末尾,因此就达到了原生SQL实现分页排序的效果
      2、可能会出现这样一个问题:查询出来的Page.content中,所有数据可能只有值,而不是“字段名:字段值”的key-value属性,那么这样的数据就没有任何意义,也无法让前端取得任何字段的值。
      解决办法:在调用方法返回的Page类型后面加上一个Map类型即可解决。

    可能大家在百度这个问题时,会发现很多回答都是在sql语句最后面加上”/#pageable/“这样一个参数,但是会发现这个并没有用,甚至还会报错:解析SQL语句出错。
    (如:https://blog.csdn.net/github_34645245/article/details/81359519 中的回答)


    这次问题是在工作中发现的,最重解决办法是根据本人慢慢摸索出来的,但是可能并不适用所有情况(如Mysql数据库、其他ORM框架等等均没有测试)。如果大家发现还存在其他问题,欢迎在评论区指正。
    
    
  • 相关阅读:
    DeepL 人工智能翻译降临 deepl.com
    Node.js ESM(ECMAScript Modules)
    解决Ubuntu 20.04 LTS无法输入中文的问题
    实现pdnsd
    颜色
    Ubuntu 20.04 LTS
    JSX 空的根元素
    如何理解TypeScript接口​​中的语法[key: string]以及[key: number]
    React-Router-DOM
    video转canvas, 并截图
  • 原文地址:https://www.cnblogs.com/fqgump/p/11164981.html
Copyright © 2020-2023  润新知