更新: タイトルを編集し、達成しようとしていることをよりよく説明するためにこのテキストを追加しました: ゼロから新しいアプリケーションを作成しようとしていますが、永続性についてビジネス層に知られたくありませんビジネス層に REST API 層を知られたくないのと同じように。以下は、使用したい永続化レイヤーの例です。これとの統合に関する適切なアドバイスを探しています。つまり、ビジネス ロジックと永続化ロジックの間で責任を明確に分割するための設計/アーキテクチャの支援が必要です。おそらく、ドメイン オブジェクトへの永続化オブジェクトのマーシャリングとアンマーシャリングに沿った概念です。
SLICK (別名 ScalaQuery)テスト例から、これは多対多のデータベース関係を作成する方法です。これにより、a、b、a_to_b の 3 つのテーブルが作成されます。a_to_b は、テーブル a と b の行のリンクを保持します。
object A extends Table[(Int, String)]("a") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def bs = AToB.filter(_.aId === id).flatMap(_.bFK)
}
object B extends Table[(Int, String)]("b") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def as = AToB.filter(_.bId === id).flatMap(_.aFK)
}
object AToB extends Table[(Int, Int)]("a_to_b") {
def aId = column[Int]("a")
def bId = column[Int]("b")
def * = aId ~ bId
def aFK = foreignKey("a_fk", aId, A)(a => a.id)
def bFK = foreignKey("b_fk", bId, B)(b => b.id)
}
(A.ddl ++ B.ddl ++ AToB.ddl).create
A.insertAll(1 -> "a", 2 -> "b", 3 -> "c")
B.insertAll(1 -> "x", 2 -> "y", 3 -> "z")
AToB.insertAll(1 -> 1, 1 -> 2, 2 -> 2, 2 -> 3)
val q1 = for {
a <- A if a.id >= 2
b <- a.bs
} yield (a.s, b.s)
q1.foreach(x => println(" "+x))
assertEquals(Set(("b","y"), ("b","z")), q1.list.toSet)
次のステップとして、これを 1 レベル上げて (まだ SLICK を使用したいのですが、うまくラップします)、オブジェクトを操作したいと思います。したがって、疑似コードでは、次のようなことを行うのが素晴らしいでしょう:
objectOfTypeA.save()
objectOfTypeB.save()
linkAtoB.save(ojectOfTypeA, objectOfTypeB)
または、そのようなもの。Java でこれにアプローチする方法についてのアイデアはありますが、純粋な OO 言語からのオブジェクト指向のアイデアのいくつかが失敗し始めていることに気付き始めています。Scalaでこの問題にどのようにアプローチするかについて、誰か私にいくつかの指針を教えてください。
例: テーブル オブジェクトをラップまたは拡張するだけの単純なオブジェクトを作成し、それらを管理する別のクラスにこれら (構成) を含めますか?
デザイナーおよびコーダーとして、この問題により適切にアプローチするのに役立つアイデア、ガイダンス、例 (お願いします) は大歓迎です。