Slick 3.1 - 检索列的子集作为案例类

2023-12-27

我正在使用 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]  

对应的案例类:

case class AuditResult (
   ProcessorId: Long,
   DispatchedTimestamp: Timestamp,
   SystemAOutput: Array[Byte],
   SystemBOutput: Array[Byte],
   IsSuccessful: Boolean,
   AuditResultId: Long = 0L
 )

最后是数据访问查询:

def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResult, Seq] = {
  auditResults.filterNot(r => r.isSuccessful)
}

我已经考虑并研究了提出的选项在这个(过时的)答案中 https://stackoverflow.com/questions/25525403/slick-optionally-including-omitting-a-large-column/25606149#25606149和别的:

  • 具有与映射到“光版本”的默认投影不同的投影AuditResult, e.g. AuditResultLight省略了这些专栏 - 尽管我尽了最大努力,但我无法完成这项工作 - 我感觉像这样should是正确的方法 - 一旦我有了“工作”投影,我仍然收到 Slick 错误“未找到匹配的形状。Slick 不知道如何映射给定类型”
  • 使用抽象构建类层次结构AuditResultTableBase类和从它派生的两个类 - 一个添加“重”列,一个不添加“重”列,两者都有各自的默认投影和案例类。这工作得很好,但这种方法似乎是错误的,并且需要对这样一个简单的事情进行相对较大的代码更改。
  • 物化元组而不是案例类 - 这当然可以,但我希望我的数据访问层是强类型的。

Slick 3.1 解决此问题的惯用/最佳实践是什么?我可以为此使用自定义投影吗?如果是的话,这个特定示例/查询会是什么样子SystemAOutput and SystemBOutput是我想省略的重列吗?


我有类似的问题!您必须定义形状!在的帮助下文档 http://slick.lightbend.com/doc/3.1.0/userdefined.html#monomorphic-case-classes我设法通过“轻型”案例类工作来实现该方法。

首先,定义更简单的类:

case class AuditResultLight(
  ProcessorId: Long,
  DispatchedTimestamp: Timestamp,
  IsSuccessful: Boolean,
  AuditResultId: Long = 0L
)

然后,您需要创建案例类的提升版本:

case class AuditResultLightLifted(
  ProcessorId: Rep[Long],
  DispatchedTimestamp: Rep[Timestamp],
  IsSuccessful: Rep[Boolean],
  AuditResultId: Rep[Long]
)

另外,您需要一个隐式对象(形状) 告诉 slick 如何将一个映射到另一个:

implicit object AuditResultLightShape 
  extends CaseClassShape(AuditResultLightLifted.tupled, AuditResultLight.tupled)

现在,您可以定义一个返回 AuditResultLight 的查询(不完全是投影,但据我了解,它的工作原理类似):

val auditResultsLight = auditResults.map(r => AuditResultLightLifted(r.ProcessorId, r.DispatchedTimestamp, r.IsSuccessful, r.AuditResultId))  

然后,您可以定义以简单形式返回失败审核的函数:

def getRecentFailedAuditsQuery(): Query[AuditResultTable, AuditResultLight, Seq] = {
  auditResultsLight.filterNot(r => r.isSuccessful)
}

代码要点:https://gist.github.com/wjur/93712a51d392d181ab7fc2408e4ce48b https://gist.github.com/wjur/93712a51d392d181ab7fc2408e4ce48b

代码编译并执行,但就我而言,问题是我的 IDE (IntelliJ) 报告Query[Nothing, Nothing, scala.Seq]键入:auditResultsLight。每当我使用时都会出现语法错误auditResultsLight并引用一个字段AuditResultLight在查询中。然而,正因为如此,最终我决定使用您建议的第二种方法(带有抽象表的方法)。代码量几乎相同,但有 IDE 支持。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Slick 3.1 - 检索列的子集作为案例类 的相关文章

随机推荐