spring-data-jpa複雑検索の書き方(orの照会を含む)

2862 ワード

記録してください.前に会ったspring-data-jpa関連業務は全部簡単に処理されました.
場面は以下の通りです.簡単なCMSでよく調べられます.小欄にはいくつかのサブ欄があります.

public class Channel{
....
private String parentIds;// , 0,1,11,
private List channels = Lists.newArrayList(); //
...
}

public class Content{
private Channel channel; //
}
たとえば、次のような構成がある場合、コラムAの下に二つのサブ欄B,Cがあります.この3つの欄にはそれぞれの内容があります.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';
考えてみれば、どうも簡単な方法がないということを発見しました.あるいは調べた後、動的な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 ?