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
相关产品推荐
相关产品推荐

