SpringDataJPA自定义SQL中替换if失效写法

191 阅读1分钟

场景【oracle数据库】:

我们使用jpa有的时候遇到多表联查不喜欢用Specifications动态查询,那么就会写自己定义的sql,如下方注解写自定义SQL。

@Query(nativeQuery = true, value = "自定义SQL") 

最近改造一个系统遇到一个场景,原先SQL是多表联查然后分页,现在需要改造成带条件查询并分页。

第一种方式:

是用Specifications实现,需要两个表实体类有关联关系,个人不是很喜欢这种用法就放弃了。

第二种方式:

后续又看到资料说可以用if语句写法,如下方例子

" AND IF(?2 is not null , INSTR(USER_NAME,?2) > 0,1=1 ) ) "

这个写法在我们这个项目里执行会报错:缺失右括号。

解决方案:

利用SQL中OR语句

@Query(nativeQuery = true, value = "SELECT epu.TENG_YUN_USER_ID,ea.USER_NAME FROM " +
        "(" +
        " SELECT USER_NAME FROM TABLE1 " +
        "WHERE OFFICENO = ?1 AND STATUS = 1 " +
        " AND ( ?2=1  or INSTR(USER_NAME,?3) > 0 ) " +
        " ) ea LEFT JOIN TABLE2 epu ON ea.USER_NAME = epu.USER_NAME", 
        countQuery = "SELECT count(*) FROM " +
        "( " +
        "SELECT epu.TENG_YUN_USER_ID,ea.USER_NAME FROM " +
        "(" +
        " SELECT USER_NAME FROM TABLE1  " +        "WHERE OFFICENO = ?1 AND STATUS = 1  " +
        " AND ( ?2=1  or INSTR(USER_NAME,?3) > 0 ) " +
        " ) ea LEFT JOIN TABLE2  epu ON ea.USER_NAME = epu.USER_NAME"        + " )")
Page<Map<String, Object>> queryOfficeSubordinateInfoListPage( String office,int flag,String userName, Pageable pageable);

前置调用处自行判空处理,如下:

Pageable pageable = PageRequest.of(queryOfficeSubordinateInfoDTO.getPage()-1, queryOfficeSubordinateInfoDTO.getSize());
    int  userNameFlag;
    if(StringUtils.isEmpty(queryOfficeSubordinateInfoDTO.getUserName())){
        userNameFlag = 1;
    }else {
        userNameFlag = 0;
    }
    Page<Map<String, Object>>  mapPage = officeSubordinateInfoRepository.queryOfficeSubordinateInfoListPage( office,userNameFlag, queryOfficeSubordinateInfoDTO.getUserName(), pageable);

此处我多传了个标识参数,可以不用,只用一个userName参数,自行定义一个标识,比如userName为空时赋值为"null",后续?2=1改为?2="null",这种会有个问题就是调用方正好传入"null"来查询,你这SQL就会查所有。