首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用Slick 3.1和DDD实现多数据库模式

如何用Slick 3.1和DDD实现多数据库模式
EN

Stack Overflow用户
提问于 2016-11-27 22:28:17
回答 1查看 522关注 0票数 1

我正在阅读Debasish的功能域和反应性域建模,我想重构一个CRUD应用程序,它实际上正在生产中。我关注的第一种方法是使用Reader monad for DI、Repository模式和ADT来管理应用程序之间的等效值(想想某个应用程序以某种方式理解的值,然后查询另一个系统的等效值)。

Debasish将存储库模式作为解耦的一种方式,因此,在我的示例中,我需要为Oracle、Postgresql和H2提供具体的实现来进行测试。我有以下非常简单的实现(基于这本书):

存储库的trait

代码语言:javascript
运行
复制
trait Repository[A, Id] {

  def query(id: Id): Try[Option[A]]
  def insert(a: A): Try[A]
  def update(a: A): Try[A]
  def delete(a: A): Try[A]

}

等价库的模块:

代码语言:javascript
运行
复制
trait EquivalenceRepository extends Repository[Equivalence, Long]{

  def query(id: Long): Try[Option[Equivalence]]
  def insert(a: Equivalence): Try[Equivalence]
  def update(a: Equivalence): Try[Equivalence]
  def delete(a: Equivalence): Try[Equivalence]

}

和中期具体实现与Slick:

代码语言:javascript
运行
复制
class EquivalenceOracleRepository extends EquivalenceRepository {

  def query(id: Long): Try[Option[Equivalence]] = {
    ???
  }

  def insert(a: Equivalence): Try[Equivalence] = {
    ???
  }

  def update(a: Equivalence): Try[Equivalence] = {
    ???
  }

  def delete(a: Equivalence): Try[Equivalence] = {
    ???
  }

}

private[repository] trait EquivalenceOracleDB{
  this: DBComponent =>

  import jdbcProfile.api._

  final case class EquivalenceDTO(
                                    originId: Int,
                                    equivalenceId: Int,
                                    creator: String,
                                    creationDate: Timestamp,
                                    isActive: Boolean
                                  )

  final class EquivalenceTable(tag: Tag) extends Table[Equivalence](tag, "Equivalence"){

    def originId: Rep[Int] = column[Int]("ORIGIN_ID", O.SqlType("NUMBER(10)"))
    def equivalenceId: Rep[Int] = column[Int]("EQUIVALENCE_ID", O.SqlType("NUMBER(10)"))
    def creator: Rep[String] = column[String]("CREATOR", O.SqlType("NUMBER(10)"))
    def creationDate: Rep[Timestamp] = column[Timestamp]("CREATION_DATE", O.SqlType("TIMESTAMP(6)"))
    def isActive: Rep[Boolean] = column[Boolean]("IS_ACTIVE", O.SqlType("VARCHAR2(1)"))

    def pk: PrimaryKey = primaryKey("EQUIVALENCES_PK", (originId, equivalenceId))

    def * : ProvenShape[EquivalenceDTO] =
      (originId, equivalenceId, creator, creationDate, isActive) <> (EquivalenceDTO.tupled, EquivalenceDTO.unapply)

  }

  val table = TableQuery[EquivalenceTable]

}

作为Oracle的最后一个具体实现,您可以看到该特性期待一个DBComponent。这是一个特性,它的代码继承自实际的生产应用程序,并试图为每个DBMS定义具体的流畅配置文件:

--这是对每个DBMS的分析:

代码语言:javascript
运行
复制
trait Profile {
  val jdbcProfile: JdbcProfile
}

object OracleProfile extends Profile {
  override val jdbcProfile: JdbcProfile = OracleDriver
}

object H2Profile extends Profile {
  override val jdbcProfile: JdbcProfile = H2Driver
}

object PostgreSQLProfile extends Profile {
  override val jdbcProfile: JdbcProfile = PostgreSQLProfile.jdbcProfile
}

,这是数据库定义:

代码语言:javascript
运行
复制
trait DBComponent {

  val jdbcProfile: JdbcProfile
  import jdbcProfile.api._
  val db: Database

}

trait OracleDB extends DBComponent {
  val logger: Logger = LoggerFactory.getLogger(this.getClass)
  val jdbcProfile: JdbcProfile = OracleProfile.jdbcProfile
}

trait H2DB extends DBComponent {
  val logger: Logger = LoggerFactory.getLogger(this.getClass)
  val jdbcProfile: JdbcProfile = H2Profile.jdbcProfile
}

trait PostgreSQLDB extends DBComponent {
  val logger: Logger = LoggerFactory.getLogger(this.getClass)
  val jdbcProfile: JdbcProfile = PostgreSQLProfile.jdbcProfile
}

但我对此表示怀疑:如果我试图将包含光滑基础知识的EquivalenceOracleDB特性混合到EquivalenceOracleRepository中,那么我也需要混合组件,实际上,我得到了一个错误:

Mixin:

代码语言:javascript
运行
复制
class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB{

错误:Illegal inheritance, self-type EquivalenceOracleRepository does not conform to DBComponent,因为接口不匹配。所以,我需要一些光:

  • 是否有一个已知的、具体的、光滑的多db实现,我可以与Debasish?公开的范例结合使用。
  • 如何改进我的具体实现的设计,使其符合书中定义的存储库模式,并且到目前为止也不影响具体和抽象的实现?(将关注点分开)

我见过Lightbend的多数据库示例,但是,除了尚未解决的依赖问题之外,它还严重依赖Cake模式,这是非常冗长的。我在努力坚持这本书。

任何帮助都将不胜感激。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-28 17:22:09

之所以会出现这样的错误,是因为您没有混合OracleDB。你应该替换:

代码语言:javascript
运行
复制
class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB

使用

代码语言:javascript
运行
复制
class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB with OracleDB

现在您将得到一个没有定义db的错误,所以您应该在某个地方提供它的实现(因为它在DBComponent中被定义为抽象的)。我认为这可以在OracleDB中实现,这将使这一特性具体化,而不是像现在这样抽象。我认为,这样您将或多或少地符合书中提出的设计(您有一个描述您的存储库的抽象接口,以及多个具体/生产实现)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40834671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档