加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 09:20:58 所属栏目:安全 来源:网络整理
导读:我正在使用Slick 3.1.1,问题是在某些情况下,我想省略一些相当沉重的列,并将该子集的列作为案例类实现. 考虑下表定义: class AuditResultTable(tag: Tag) extends Table[AuditResult](tag,AuditResultTableName) { def auditResultId: Rep[Long] = column[Lo
我正在使用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和其他方面的选择:

>与默认投影相比,映射到“审计结果”的轻型版本,例如忽略这些列的AuditResultLight – 尽管我尽力而为,我无法做出这样的工作 – 我觉得这应该是正确的方法 – 一次我有一个“工作”的投影我还有一个Slick错误“找不到匹配的形状. Slick不知道如何映射给定的类型“
>使用抽象的AuditResultTableBase类和从其派生的两个类构建类层次结构 – 一个添加“重”列和一个没有它们的两个都具有各自的默认投影和案例类.这很好,但是这种方法似乎是错误的,并且需要相对较大的代码改变来做这样一件容易的事情.
>实现元组而不是案例类 – 这当然可以工作,但我希望我的数据访问层被强制类型化.

对于这个问题,Slick 3.1的习语/最佳做法是什么?我可以为此使用自定义投影,如果是,这个特定示例/查询与SystemAOutput和SystemBOutput是什么样子是我想要忽略的重列?

解决方法

我也有类似的问题!你必须定义Shape!在 documentation的帮助下,我设法使“轻”案例班工作.

首先,定义更简单的类:

case class AuditResultLight(
  ProcessorId: Long,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)报告auditResultsLight的Query [Nothing,Nothing,scala.Seq]类型.每当我使用auditResultsLight并在查询中引用AuditResultLight的字段时,我会收到语法错误.但是,因为这样,最终我决定使用你建议的第二种方法(一个是抽象表).几乎相同的代码量,但是支持IDE.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读