更新:我编辑了标题并添加了这段文字,以更好地解释我想要实现的目标:我正在尝试从头开始创建一个新应用程序,但不希望业务层知道持久性层,就像我们不希望业务层知道 REST API 层一样。下面是我想使用的持久层的示例。我正在寻找与此集成的好建议,即我需要设计/架构方面的帮助,以清晰地划分业务逻辑和持久性逻辑之间的职责。也许是一个将持久性对象编组和解组为域对象的概念。
从 SLICK(又名 ScalaQuery)测试示例中,这就是您创建多对多数据库关系的方式。这将创建 3 个表:a、b 和 a_to_b,其中 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)
作为我的下一步,我想把它提升一个层次(我仍然想使用 SLICK,但很好地包装它)来处理对象。所以在伪代码中做这样的事情会很棒:
objectOfTypeA.save()
objectOfTypeB.save()
linkAtoB.save(ojectOfTypeA, objectOfTypeB)
或类似的东西。我对如何在 Java 中实现这一点有自己的想法,但我开始意识到,我从纯 OO 语言中获得的一些面向对象的想法开始让我失望。谁能给我一些关于如何在Scala中解决这个问题的指示。
例如:我是否创建了仅包装或扩展表对象的简单对象,然后将这些(组合)包含到另一个管理它们的类中?
任何想法,指导,示例(请),将帮助我作为设计师和编码人员更好地解决这个问题,将不胜感激。