本文是個人原創,轉載請說明文章出處。
使用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;
}
}
代碼都經測試,如有錯誤之處,希望共同交流指正。