SpringData Jpa 使用@Query解决多表查询、模糊查询(空字段或者null判断)、排序、分页功能

本文是个人原创,转载请说明文章出处。

此文数据库为mysql

使用jpa非常方便,可是感觉灵活性不如mybatis高,特别是自定义的查询语句,往往无从下手,还好jpa提供了@Query注解,可以通过自定义原生的sql来查询,这用起来就和mybatis一样爽了,虽然入侵了代码,但是从实现上来说,也并不是不可取的。毕竟用hibernate封装的一些查询来处理业务,在遇到需要修改查询条件的时候,大多情况下还是要入侵代码的,所以这里不考虑应用的扩展,只是把自己使用过程中遇到的一些问题提供给大家,有更好的方案,欢迎留言。
只贴一个接口和测试类,其他的请自行参考。
Repository接口

public interface AbcRepository extends JpaRepository<Abc, String>, JpaSpecificationExecutor<Abc> {

 @Query(value = "SELECT a.* FROM abc" +
         "INNER JOIN (SELECT script_name,MAX(date_created) 'date_created' FROM abc" +
         "GROUP BY script_name) b " +
         "ON a.script_name = b.script_name  " +
         "AND a.date_created = b.date_created " +
         "AND IF(ifnull(?1,'') != '',a.script_name LIKE CONCAT('%',?1,'%'),1=1) " +
         "AND IF(ifnull(?2,'') != '',a.script_status LIKE CONCAT('%',?2,'%'),1=1) " +
         "AND IF(ifnull(?3,'') != '',a.script_flag LIKE CONCAT('%',?3,'%'),1=1) " +
         "AND IF(ifnull(?4,'') != '',a.level_one=?4,1=1) order by ?#{#pageable}",
         countQuery = "SELECT a.* FROM job_script a " +
                 "INNER JOIN (SELECT script_name,MAX(date_created) 'date_created' FROM job_script " +
                 "GROUP BY script_name) b " +
                 "ON a.script_name = b.script_name  " +
                 "AND a.date_created = b.date_created " +
                 "AND IF(ifnull(?1,'') != '',a.script_name LIKE CONCAT('%',?1,'%'),1=1)" +
                 "AND IF(ifnull(?2,'') != '',a.script_status LIKE CONCAT('%',?2,'%'),1=1) " +
                 "AND IF(ifnull(?3,'') != '',a.script_flag LIKE CONCAT('%',?3,'%'),1=1) " +
                 "AND IF(ifnull(?4,'') != '',a.level_one=?4,1=1)",
         nativeQuery = true)
 Page<abc> findJobScriptsByConditons(String scriptName,
                                           String scriptStatus,
                                           String scriptFlag,
                                           String levelOne,
                                           Pageable pageable);
}

测试类:

    @Test
    public void queryJobScriptByCondition() {
        Page<abc> auto = this
                .jobScriptRepository
                .findJobScriptsByConditons(
                        "",
                        "1",
                        "AUF",
                        "AUF",
                        new PageRequest(0,5));

        System.out.println("============================总数:" + auto.getTotalElements());
    }

可以将参数Pageable类封装成带排序的工具类,但是使用原生的sql时候,传入的排序字段必须是mysql数据库对应的,而不是实体对应的字段,比如最后一个参数new PageRequest(0,5)可以改为:

PageUtil.buildPageable(currentPage,
                       rows,
                       Sort.Direction.DESC,
                       "date_created") //此处若是原生的SQL,必须用mysql数据库字段,而不是实体类的驼峰命名的字段dateCreated

封装后的分页工具类:


public class PageUtil {

    public static Pageable buildPageable(int page, int size, Sort.Direction direction, String... orderFields) {
        Sort sort = null;
        Pageable pageable;
        if (null != orderFields && orderFields.length > 0) {
            if (null != direction) {
                sort = new Sort(direction, orderFields);
            } else {
                sort = new Sort(Sort.Direction.ASC, orderFields);
            }
        }
        if (null == sort) {
            pageable = new PageRequest(page, size);
        } else {
            pageable = new PageRequest(page, size, sort);
        }
        return pageable;
    }
}

代码都经测试,如有错误之处,希望共同交流指正。

评论 17 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

江湖上最后一块奶酪

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值