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 ?

0

0

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2013-11-04 12:05

浏览 67318

评论

2 楼

endual

2017-10-07

想要查询这样channel,其子栏目 channels 数列里面的channel的名字包含“新闻”?

请问这要怎么操作?

1 楼

814687491

2013-11-04

感觉好复杂,不懂你想描述什么!

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)

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐