持久层抽象[光滑]

问题描述 投票:1回答:1

我有一个关于持久层抽象的问题。

目标

创建一个不具有Slick相关性的结构,因此实体必须与Slick和Slick-repo插件脱节。


现在的情况

环境

  • 比例%2.12.4
  • com.typesafe.play%sbt-plugin%2.6.12
  • com.typesafe.play%play-slick%3.0.3
  • com.byteslounge%Slick-repo%1.4.3

目前我已经创建了具有以下特征的抽象:

IRepository:

trait IRepository[E <: Entity[E, ID], ID] {

  type Transaction[T]

  val transactionManager: TransactionManager[Transaction]
  final type EntityType = E

  def findAll()(implicit ec: ExecutionContext): Transaction[Seq[E]]
  def findOne(id : ID)(implicit ec: ExecutionContext): Transaction[Option[E]]
  def lock(entity: E)(implicit ec: ExecutionContext): Transaction[E]
  def save(entity: E)(implicit ec: ExecutionContext): Transaction[E]
  def batchInsert(entities: Seq[E]): Transaction[Option[Int]]
  def update(entity: E)(implicit ec: ExecutionContext): Transaction[E]
  def delete(entity: E)(implicit ec: ExecutionContext): Transaction[E]
  def count(): Transaction[Int]
  def exclusiveLockStatement(sql: String): String
}

事务管理:

trait TransactionManager[T[_]] {

  final type Transaction[Entity] = T[Entity]

  implicit def executeAll[Entity](op: Seq[T[Entity]]): Future[Seq[Entity]]

  implicit def execute[Entity](op: T[Entity]): Future[Entity]
}

实体:

trait Entity[T <: Entity[T, ID], ID] {

  final type IdType = ID

  val id: Option[ID]

  def withId(id: ID): T
}

在服务中,我使用隐式转换scala功能来执行Db操作并获取Future实例

这是一个简单的例子:

class UserServiceImpl @Inject()(private val repo: UserRepository)
                               (implicit ec: ExecutionContext) extends UserService {

  import repo.transactionManager._

  override def retrieve(id: Long): Future[Option[User]] =
    repo.findOne(id)

  override def save(user: User): Future[User] =
    repo.save(user)

  override def retrieve(loginInfo: LoginInfo): Future[Option[User]] =
    repo.findByLoginInfo(loginInfo)

  override def delete(user: User): Future[User] =
    repo.delete(user)
}

问题

所有这些抽象都需要实现,这里问题就出现了。

我认为我必须放弃存储库抽象,因为不经意地使用光滑的BDIO方法,我需要具体访问它,这将我的代码绑定到Slick但我认为没关系。

实体与我的特性(实体)无关,但问题在于与repos集成。

我的slick repos从Slick-repo插件扩展了Repository类,这些类(比如我的IRepository trait)需要两个泛型类型,第一个必须扩展一个名为Entity的特征(Slick-repo的特征),而第二个没有约束并代表实体的id类型。

综上所述:

我的课程

  • IRepository [实体,ID]
  • 实体[实体,ID]
  • Slick Repository [Entity,ID]扩展了Repository

光滑回购课程

  • 存储库[实体,ID]
  • 实体[实体,ID]

SlickRepository扩展/应该使用Repository(Slick-repo),但该类希望第一个泛型参数释放Entity(Slick-repo),而在我的情况下,为了分离,它扩展了Entity trait(我的域特征)

我希望很清楚,我知道这种情况很复杂,特别是因为某些班级有相同的名字

也许我对这个问题的概念是完全错误的我不知道我希望有人可以帮助我。

感谢所有的建议。

scala playframework architecture slick abstraction
1个回答
1
投票

您可以在此处查看Slick的持久层抽象示例:https://github.com/gonmarques/slick-repo

此repo提供了以下常见功能:

  • 以类型安全的方式提供常见的数据库操作,如保存,更新,查找,删除或计数
  • 其他操作,如交易,批量插入,乐观锁定(又名版本控制),
  • 还支持悲观锁定或自定义查询/语句执行
  • 为了最大限度地提高性能,所有提供的操作都由Slick编译查询支持,如Slick Documentation中所建议的那样
© www.soinside.com 2019 - 2024. All rights reserved.