SpringData Jpa 使用@Query解决多表查询、模糊查询、排序、分页功能

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

使用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;
    }
}

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章