本文是个人原创,转载请说明文章出处。
使用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;
}
}
代码都经测试,如有错误之处,希望共同交流指正。