You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala Slick抽象表实现后,如何向通用仓库传递TableQuery?

没问题,我来帮你搞定这个Slick通用仓库的传参问题!

你的核心问题是现在的通用仓库类接收的是单个TableDef实例,但Slick里我们实际用来做查询的是TableQuery——它是Slick封装表查询逻辑的核心容器,所以只需要调整仓库的构造参数和泛型约束,就能轻松把TableQuery传进去。

第一步:修改通用仓库类

把仓库的构造参数从TableDef改成TableQuery[TableDef],这样就能直接接收你定义的TQDomain这类TableQuery实例了:

class SubResourceCommonRepository[Entity <: SubResource, A, I, U, TableDef <: SubResourceTabledef[Entity, A, I, U]](
  val tableQuery: TableQuery[TableDef]
) {
  // 这里可以实现通用的CRUD逻辑,举个异步查询的例子:
  def findById(id: Long)(implicit ec: ExecutionContext, db: Database): Future[Option[Entity]] = {
    db.run(tableQuery.filter(_.id === id).result.headOption)
  }

  // 如果要用到你抽象表中的映射方法(比如insertMapped),可以通过tableQuery.baseTableRow拿到表定义实例:
  def insert(entity: I)(implicit ec: ExecutionContext, db: Database): Future[Entity] = {
    val insertProjection = tableQuery.baseTableRow.insertMapped
    db.run((tableQuery returning tableQuery.map(_.allMapped)) += insertProjection.unapply(entity).get)
  }
}

第二步:创建仓库实例

现在直接把你的TableQuery对象传进去就行,Scala的类型推导会帮你自动补全泛型参数,不用手动写一大串:

// 假设你的TQDomain是对应SomeThingResourceTabledef的TableQuery
val someThingRepository = new SubResourceCommonRepository(TQDomain)

为什么这么做?

TableQuery本身就包含了表的定义逻辑——你创建TQDomain的时候用的new ArticleGoodsMovementTabledef(_),其实是给TableQuery提供了创建表实例的工厂方法。所以仓库接收TableQuery后,既可以用来构建查询,也能通过baseTableRow获取到抽象表的所有映射方法,完美适配你的抽象设计。

如果之后需要扩展通用逻辑,比如批量更新、分页查询,都可以在这个仓库类里统一实现,所有继承SubResourceTabledef的具体表都能复用这些逻辑。

内容的提问来源于stack exchange,提问作者FrancMo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:11:41