场景【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就会查所有。