Bro*_*ass 17 scala slick slick-3.0
我正在使用Slick 3.1.1,问题是在某些情况下我想省略一些相当重的列,并且仍然将列的子集实现为案例类.
请考虑以下表定义:
class AuditResultTable(tag: Tag) extends Table[AuditResult](tag, AuditResultTableName) {
def auditResultId: Rep[Long] = column[Long]("AuditResultId", O.PrimaryKey, O.AutoInc)
def processorId: Rep[Long] = column[Long]("ProcessorId")
def dispatchedTimestamp: Rep[Timestamp] = column[Timestamp]("DispatchedTimestamp", O.SqlType("timestamp(2)"))
def SystemAOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemAOutput", O.SqlType("LONGBLOB"))
def SystemBOutput: Rep[Array[Byte]] = column[Array[Byte]]("SystemBOutput", O.SqlType("LONGBLOB"))
def isSuccessful: Rep[Boolean] = column[Boolean]("IsSuccessful")
def * : ProvenShape[AuditResult] = (processorId, dispatchedTimestamp, systemAOutput, systemBOutput, isSuccessful, auditResultId) <>
(AuditResult.tupled, AuditResult.unapply)
}
val auditResults = TableQuery[AuditResultTable]
Run Code Online (Sandbox Code Playgroud)
相应的案例类:
case class AuditResult (
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
SystemAOutput: Array[Byte],
SystemBOutput: Array[Byte],
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)
Run Code Online (Sandbox Code Playgroud)
最后是数据访问查询:
def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResult, Seq] = {
auditResults.filterNot(r => r.isSuccessful)
}
Run Code Online (Sandbox Code Playgroud)
我已经考虑并研究了这个(过时的)答案和其他人提出的选项:
AuditResult
,例如AuditResultLight
省略那些列 - 尽管我付出了最大的努力但我无法做到这一点 - 我觉得这应该是正确的方法 - 一旦我有了"工作"投影我仍然有一个光滑的错误"找不到匹配的形状.Slick不知道如何映射给定的类型"AuditResultTableBase
类和从中派生的两个类构建一个类层次结构- 一个添加"重"列,另一个不添加它们,两者都有各自的默认投影和案例类.这很好用,但这种方法似乎是错误的,需要一个相对较大的代码更改才能实现这么简单的事情.对于这个问题,Slick 3.1的惯用/最佳实践是什么?我可以使用自定义投影此,如果这样你会看起来像与这个特殊的例子/查询SystemAOutput
和SystemBOutput
被重列我想省略?
我有类似的问题!你必须定义形状!在文档的帮助下,我设法使用"轻量级"案例类工作.
首先,定义更简单的类:
case class AuditResultLight(
ProcessorId: Long,
DispatchedTimestamp: Timestamp,
IsSuccessful: Boolean,
AuditResultId: Long = 0L
)
Run Code Online (Sandbox Code Playgroud)
然后,您需要创建案例类的提升版本:
case class AuditResultLightLifted(
ProcessorId: Rep[Long],
DispatchedTimestamp: Rep[Timestamp],
IsSuccessful: Rep[Boolean],
AuditResultId: Rep[Long]
)
Run Code Online (Sandbox Code Playgroud)
此外,您需要一个隐式对象(Shape)来告诉光滑如何将一个映射到另一个:
implicit object AuditResultLightShape
extends CaseClassShape(AuditResultLightLifted.tupled, AuditResultLight.tupled)
Run Code Online (Sandbox Code Playgroud)
现在,您可以定义一个返回AuditResultLight的查询(不完全是一个投影,但据我所知,它的工作方式类似):
val auditResultsLight = auditResults.map(r => AuditResultLightLifted(r.ProcessorId, r.DispatchedTimestamp, r.IsSuccessful, r.AuditResultId))
Run Code Online (Sandbox Code Playgroud)
然后,您可以定义以灯光形式返回失败审核的函数:
def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResultLight, Seq] = {
auditResultsLight.filterNot(r => r.isSuccessful)
}
Run Code Online (Sandbox Code Playgroud)
代码的要点:https://gist.github.com/wjur/93712a51d392d181ab7fc2408e4ce48b
代码编译并执行,但在我的情况下,问题是我的IDE(IntelliJ)报告Query[Nothing, Nothing, scala.Seq]
类型auditResultsLight
.每当我使用时都会出现语法错误,auditResultsLight
并AuditResultLight
在查询中引用某个字段.但是,正因为如此,我最终决定使用你建议的第二种方法(带有抽象表的方法).几乎相同数量的代码,但支持IDE.