2017-09-05 22 views
0

私は永続化層にSpring Data JPAを使ってwebappを書いています。具体的には、私のDAOはJpaSpecificationExecutorインターフェースを拡張しています。いくつかの属性(私は明確化のために注釈や他のメタデータを省略)とItemのリストを想像:私のサービス層の上にJpaフィールドの値のサブセットを見つけるための仕様

data class Item(var tags: MutableList<String>) 

、私のフィルタ方法は、次のようになります。

fun findBy(tagsToFilterBy: List<String>): List<Items> { 
    return dao.findAll { root, query, builder -> 
     builder.//?? 
    } 
} 

私が欲しいもの達成するためには、tagsToFilterByを正確に含むItemを取得することです。つまり、tagsToFilterByは、Item.tagsのサブセットにする必要があります。

私は約isMember(...)メソッドについて知っていますが、それは呼び出し時に単一の "エンティティ"だけを受け入れるので、多くのタグではそれほど楽しいものではないと思います。私に何かアドバイスできますか?

私の他の質問は、builder.like(someExpression, inputFromUser)と言うユーザー入力を直接使用するのが安全かどうか、あるいはbuilder.parameter(...)に入れてからquery.setParameter(...)に入れなければならないということです。

答えて

0

一つの方法は、フィルタを使用して、フィルタリストは、それが含まれているかどうかを確認するために、各要素をテストすることです任意のアイデアをいただき、ありがとうございます。それをスピードアップするため

val result = dao.filter { tagsToFilterBy.contains(it.tag) } 

、あなたはあなたの並べ替え、フィルタリストを強制し、多分binarySearchを使用していますが、パフォーマンスの向上(またはしない)フィルタリストのサイズに依存することができます。例えば、仮定tagsToFilterByは、その後、ソートされ:

val result2 = dao.filter { tagsToFilterBy.binarySearch(it.tag) >= 0 } 

Kotlin Collectionページは、これらの拡張メソッドの各々を記述する。

+0

私は、フィルタリングする属性が増えていることを忘れていました。そのため、「仕様」を使用する必要があります –

+0

私は問題を解決したコードを投稿しました。 –

0

私は自分で書くことができました。これは基本的に与えられたタグを通過し、それはタグのメンバーであるかどうかをチェックしている

dao.findAll { root, query, builder -> 
    val lst = mutableListOf<Predicate>() 
    val tagsPath = root.get<List<Tag>>("tags") 
    tagsToFilterBy.forEach { 
     lst.add(cb.isMember(it, tagsPath)) 
    } 
    cb.or(*lst.toTypedArray()) 
} 

:私は来ることができ、私はそれがかなりあることを言っていないんだけど、それはきれいなものです。

関連する問題