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

标签 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]  


对应的案例类:

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)
}


我考虑并研究了in this (outdated) answer和其他选项:


与默认的投影不同,它的投影与AuditResult的浅色版本(例如AuditResultLight)相对应,而忽略了这些列-尽管尽我最大的努力,我仍然无法完成这项工作-我觉得这应该是正确的方法-投影完成后,仍然出现Slick错误“找不到匹配的Shape。 Slick不知道如何映射给定的类型”
用抽象的AuditResultTableBase类和派生自其的两个类构建一个类层次结构-一个添加“重载”列,一个不添加“重载”列,分别具有各自的默认投影类和案例类。这很好用,但是这种方法似乎是错误的,并且需要相对较大的代码更改才能做到这一点。
实现元组而不是案例类-这当然可以,但是我希望我的数据访问层是强类型的。


对于此问题,Slick 3.1的惯用/最佳实践是什么?我可以为此使用自定义投影吗?如果是这样,对于此特定示例/查询,SystemAOutputSystemBOutput是我要忽略的较重的列,会是什么样?

最佳答案

我有类似的问题!您必须定义形状!在documentation的帮助下,我设法通过“轻量级”案例类来实现该方法。

首先,定义更简单的类:

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]
)


另外,您需要一个隐式对象(Shape)来告诉滑模如何将一个映射到另一个:

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

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

关于scala - Slick 3.1-将列的子集作为案例类检索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39781193/

相关文章:

scala - [SlickException : Read NULL value for column (USERS/670412212). LOGIN_ID]

scala - 在 Slick 3.0 中,有一种方法可以在不使用特定 JDBC 驱动程序的情况下声明表

postgresql - 在 Slick 表定义中使用数据库函数 - 如何?

scala - 如何在 HBase 中编码 float/double/integer 值?

scala - 在 Play Framework WebSocket 中广播消息

Scala随机森林特征重要性提取与名称(标签)

java - spark如何向集群发送作业?

scala - Slick 写一个简单的建表函数

Scala Playframework 并非所有数据库查询都会执行

scala - * 案例类投影