Database 在客户端和服务器之间共享的代码中表示DB实体的惯用方法

Database 在客户端和服务器之间共享的代码中表示DB实体的惯用方法,database,scala,slick,shapeless,scala.js,Database,Scala,Slick,Shapeless,Scala.js,假设我有一个RDBMS表persons,其中有name列(String)和age列(Int)。如果我们不需要服务器端的id,那么这可以完全适合案例类Person(name:String,age:String)。问题是,在某些情况下,我们有id,比如从DB(后端)获取person,但有时我们没有id,比如在表单(前端)中创建person 我认为有三种最简单的方法: 通过转换创建不同的类FrontendPerson和BackendPerson。非常简单,没有直接联系 添加包装DbItem(id:L

假设我有一个RDBMS表
persons
,其中有name列(
String
)和age列(
Int
)。如果我们不需要服务器端的id,那么这可以完全适合
案例类Person(name:String,age:String)
。问题是,在某些情况下,我们有id,比如从DB(后端)获取person,但有时我们没有id,比如在表单(前端)中创建person

我认为有三种最简单的方法:

  • 通过转换创建不同的类
    FrontendPerson
    BackendPerson
    。非常简单,没有直接联系
  • 添加包装
    DbItem(id:Long,person:person)
  • 添加
    id:Option[Long]
    。非常样板,在大多数情况下,我们知道
    id
    是可用的,因此
    选项#get
    将传播

我想知道是否有更好的方法(可能更通用,不成形)或集成到doobie方式中。

有一个使用默认参数的技巧:

case class Person(name: String, age: Int, id: Long = 0L)
因为
id
列位于case类的末尾,并且有一个默认值,所以可以有效地忽略它。例如,您可以通过匹配
id
创建it实例

这只有在以下情况下才有意义:

  • id
    是数据库中的一个autoinc列,因此您不必自己管理它

  • Person
    的实例将从数据库中提取,因此
    id
    字段将为任何想要使用它的人填充


它解决了你的大部分顾虑。但是+1到@triggerNZ链接到tpolcat演示文稿,以一种有原则的方式来解决这个问题。

有一个视频讨论了scala中的这个确切问题: