java能写复杂的查询么_spring-data-jpa 复杂查询的写法(包含or的查询)
場景如下:很簡單的CMS常用查詢,欄目下有多個子欄目,子欄目有包含內容。
public?class?Channel{
....
private?String?parentIds;//所有的父節點,簡化查詢策略?例如?0,1,11,
private?List?channels?=?Lists.newArrayList();?//所有的兒子欄目
...
}
public?class?Content{
private?Channel?channel;?//屬于哪個欄目
}
所以比如有如下結構時:欄目A下有兩個子欄目B,C;這三個欄目下都有各自的內容, 那么當查詢A下的內容時,肯定也是要包含B,C欄目下的內容。
比如說A欄目的id是 10 ,再加上別的查詢條件的話, 也就是說 sql 語句肯定是類似:
select?*?from?Content?as?s?where?(s.channel.id?=?10?or?s.channel.parentIds?like?'%,10,%')?and?s.yyy?=?'xxxxx'?and?s.xxx?=?'yyyy';
想來想去發現實在沒有簡單的辦法做or查詢之后跟動態的and查詢參數,好像只能自己構造,所以在此記錄一下,避免忘記。
此處動態的and 查詢條件構造是使用了springside的方法。并且我不知道這樣的構造方法是不是spring-data-jpa的標準做法,如果不是,請指正
/**
*?查詢某個欄目下的所有文章,并且分頁。
*
*?如該欄目下有子欄目,則需要一起顯示
*
*?@param?channelId?欄目id
*?@param?searchParams
*?@param?pageNumber
*?@param?pageSize
*?@return
*/
public?Page?getContentListPaged(final?Integer?channelId,final?Collection?filters,int?pageNumber,?int?pageSize){
return?contentDao.findAll(new?Specification(){
@Override
public?Predicate?toPredicate(Root?root,
CriteriaQuery>?query,?CriteriaBuilder?builder)?{
//path轉化
List?orPredicates?=?Lists.newArrayList();
Path?idPath?=?root.get("channel").get("id");
Path?parentIdsPath?=?root.get("channel").get("parentIds");
Predicate?p1?=?builder.equal(root.get("channel").get("id"),?channelId);
orPredicates.add(builder.or(p1));
Predicate?p2?=?builder.like((Path)root.get("channel").get("parentIds"),?"%,"?+?channelId?+?",%");
orPredicates.add(builder.or(p2));
//以下是springside3提供的方法
Predicate?o?=?DynamicSpecifications.bySearchFilter(filters,?Content.class).toPredicate(root,?query,?builder);
Predicate?p?=?builder.or(orPredicates.toArray(new?Predicate[orPredicates.size()]));
query.where(p,o);
return?null;
}
},?new?PageRequest(pageNumber?-?1,?pageSize));
}
實際查詢的輸出sql如下,where之前省略:
where
content0_.channel_id=channel1_.id
and?(
content0_.channel_id=21
or?channel1_.parentIds?like??
)
and?(
content0_.title?like??
)?limit??
另一個使用案例:
前端返回的查詢結構:{"字段名1":"字段值1","字段名2":"字段值2"}
Sort sort = new Sort(Sort.Direction.DESC, "id");
Pageable pageable = new PageRequest(page<0?0:page, size<0?1:size, sort);
if(filters != null){
JSONObject params = JSON.parseObject(filters);
Set keys = params.keySet();
if(keys.size() > 0){
Specification spec = new Specification() {
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
List andPredicates = Lists.newArrayList();
for(String key : keys){
if(StringUtils.isNotBlank(params.getString(key)))andPredicates.add(cb.like(root.get(key),"%"+params.getString(key)+"%"));
}
Predicate p = cb.and(andPredicates.toArray(new Predicate[andPredicates.size()]));
query.where(p);
return null;
}
};
return logViewManager.findAll(spec,pageable);
}
}
總結
以上是生活随笔為你收集整理的java能写复杂的查询么_spring-data-jpa 复杂查询的写法(包含or的查询)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS中背景颜色、背景图片、渐变色、背景
- 下一篇: js splice方法_我用JS刷Lee