私たちは、Scalaでは、当社のデータ・アクセスのためのリポジトリのパターンを使用していて、これまでのところ、我々は我々のRepository[A]
トレイトでこのようなものがあります:Scalaでリポジトリパターンをスケールする方法は?
trait Repository[A] {
/**
* Create a new record in the database.
*
* @param model
* @param connection
* @return
*/
def create(model: A)(implicit connection: Connection): A
/**
* Retrieve a record from the database with the corresponding id.
*
* @param id
* @param connection
* @return
*/
def getById(id: UUID)(implicit connection: Connection): Option[A]
/**
* Update the corresponding record in the database.
*
* @param model
* @param connection
* @return The updated model, or None if it was not found
*/
def update(model: A)(implicit connection: Connection): Option[A]
/**
* Delete a record from the database with the corresponding id.
*
* @param id
* @param connection
* @return The deleted model, or None if it was not found
*/
def deleteById(id: UUID)(implicit connection: Connection): Option[A]
}
をそして、それは大丈夫です。この問題は、「クエリ」メソッドにあります。例えば、私はどこのすべてのブログ記事を取得するためのメソッドを持っていると想像:
- は、ユーザーIDがXである、または
- ユーザーは、私もブログのオブジェクトを含めるゲスト
です。
def getWithBlogByUserIdOrUserGuest(userId: UUID, guest: Boolean): List[Post]
これはかなり醜いです、そしてあなたは(長い名前を持っている)エンティティとの関係の束を返すようにしたい場合は、それは手に負えなくなることができます。私たちの現在の制度では、我々はこのようなメソッドを持っているでしょう早く。ある種の一貫性を加えるために形質を使用することも難しいです。
私は見てきたいくつかの例には、クエリオブジェクトを使用するために、次のとおりです。
def query(criteria: Criteria): List[A]
はしかし、これは基準を定義するためのDSLのいくつかの並べ替えを考え出す必要があり、それはまた、基準を変換書き込みコードが必要SQLにはエラーが発生しやすく、多くの作業が必要となり、おそらくはうまくいくでしょう。
私の質問は、ほとんどの人がリポジトリにクエリメソッドを書くための一般化された方法を持っているとどのように対処するのでしょうか?
これは、「一般化された」という意味に大きく依存します。 SQLに多かれ少なかれ同等の意味があるなら、それは少し尋ねます。しかし、時期尚早に最適化していますか?アプリケーションで実際にどのような質問をしますか?場合によっては、クライアントがより簡単なクエリを実行し、結果自体をさらにフィルタリングするのが最適ですか? –
@TheArchetypalPaul:今は 'getOneWithWidgetAndTaskTemplateByChecklistRevisionIdAndWidgetId'のような実際のメソッドがあり、私はそれよりも優れた方法を探しています。これは一般的な基準APIである必要はなく、メソッドを定義するための管理が容易な方法です。 – cdmckay
ジェネリックである必要がありますか?私の経験では、ビジネスコードがオブジェクトを取得してそのメソッドをコード化するだけの意味があります。 YAGNIが適用されます! – Paolo