0

我正在阅读Debasish Ghosh的Functional And Reactive Domain Modeling,我想重构它实际上正在生产的CRUD应用程序。 我正在关注第一种使用Reader monad进行DI,Repository模式和ADT的第一种方法,用于管理应用程序之间等价值的应用程序(想想一个值,通过某种应用程序以某种方式理解,然后查询另一个应用程序的等价值系统)。如何使用Slick 3.1和DDD实现多数据库模式

Debasish提到存储库模式作为解耦的一种方式,所以,在我的情况下,我需要Oracle和Postgresql和H2的具体实现来进行测试。 我有以下的和非常简单的实现(基于书):

基地trait为库:

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] 

} 

模块的等效库:

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] 

} 

中途混凝土 impl ementation用油滑:

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剖析:

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 
} 

这是数据库定义:

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特质包含油滑基础知识我n要EquivalenceOracleRepository还我需要混入的成分,实际上我得到一个错误:

密新:

class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB{ 

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

  • 有,我可以结合由Debasish暴露范式使用已知的具体油滑多分贝的实现?
  • 我怎么能提高我的具体落实为是符合书中定义的存储库模式,也不能搞乱了具体和抽象实现截至目前的设计?(保持关注分离)

我见过the Multi-DB example that Lightbend has,但是,除了未解决的依赖性问题严重依赖蛋糕上的模式,这是非常详细。我试图坚持这本书。

任何帮助将不胜感激。

感谢

回答

1

你得到这种错误的原因是,你不混合OracleDB。此时应更换:

class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB 

class EquivalenceOracleRepository extends EquivalenceRepository with EquivalenceOracleDB with OracleDB 

现在你会得到db没有定义的错误,所以你应该某处提供其实现(因为它在DBComponent定义为抽象的)。我认为这可以在OracleDB中完成,它会使这个特质具体化,而不像现在这样抽象。我认为这样你或多或少会遵守书中提出的设计(你有一个描述你的Repository的抽象接口,以及多个具体/生产实现)。

+0

就是这样!另外,我不得不说,我已经在twitter上询问了Debasish(https://twitter.com/AlejandroM_E/status/803003856124870656),他用这个有用的帖子解决了多分贝问题:http://leaks.wanari。 COM/2016/08/17 /环境依赖的数据库的驱动程序,柔滑/。 –