案例类中的Scala Option类型

时间:2013-12-30 05:55:20

标签: scala case-class

我有一个案例类,它的一些字段作为选项类型。请考虑以下案例类:

case class TypeA(field1: Int, field2: Option[String], field3: Boolean)

此案例类将由持久层实例化,该层调用数据库表并返回此案例类的实例。 field2的值来自数据库中的另一个表,几乎在所有情况下,返回TypeA的方法都不需要设置field2。通过执行数据库查找返回TypeA后,将设置field2的值。我想在TypeA中使用field2但我不希望将其作为TypeA构造函数的一部分。部分功能,特征浮现在我的脑海中,但由于我是Scala的新手,我正在寻找一些好的做法。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

如果我很了解您的情况,您可以按照以下步骤操作:

case class TypeA(field1: Int, field3: Boolean) {
  lazy val field2 = YourDAO.lookup
}

请注意,在此解决方案中,field2是延迟填充的,始终依赖于数据库查找。

答案 1 :(得分:1)

这会达到你想要的效果吗?

case class TypeA(
  field1: Int,
  field2: Option[String] = None,
  field3: Boolean
)

val a = TypeA(field1 = 7, field3 = true)
// a: TypeA = TypeA(7,None,true)

val b = a.copy(field2 = Some("x"))
// b: TypeA = TypeA(7,Some(x),true)

答案 2 :(得分:0)

实际上,如果您阅读了两个表,然后从中创建了一些聚合实体,我建议您考虑两种方法:

1)也许您可以进行外部联接查询,这将使您返回具有Option [T]参数的实体。在我们的项目中,我们使用Squeryl ORM。你可以检查一下: http://squeryl.org/joins.html

   val query = join(typeATable, typeBTable.leftOuter)((a,b) =>
    select((a, b))
    on(a.someField === b.anotherField.?)
   )
   val result: List[(TypeA, Option[TypeB])] = query.toList

这样的查询将返回List [(TypeA,Option [TypeB])]

然后你可以将它映射到你想要的某个TypeC

2)另一种解决方案:创建两个DAO服务,它们将从数据库中读取。然后制作聚合器服务,它将结合结果:

TypeA - 基本特征,会有不同的推理

trait TypeA {
  def field1: Int
  def field2: Option[String]
  def field3: Boolean
}

SimpleTypeA - 您从DB读取的实体。它有field2 as None你想要^

case class SimpleTypeA(
  field1: Int,
  field3: Boolean
) extends TypeA {
  val field2: Option[String] = None
}

TypeB - 您从DB收到的其他类型:

case class TypeB(...)

然后,AggregatedTypeA - 实体,将从两个数据库中汇总信息:

case class AggregatedTypeA(
  entity: TypeA,
  anotherEntity: Option[TypeB]
) extends TypeA {
  def field1 = entity.field1 
  //retrive info from anotherEntity: Option[TypeB]
  def field2 = anotherEntity.map(_.someFieldOrMethod)
  def field3 = entity.field3 
}

然后实施服务:

从DB中选择SimpleTypeA

trait TypeADAOService {
   def select(...): List[TypeA] //List[SimpleTypeA]
}

在DB中查找TypeB

trait TypeBDAOService {
   def lookup(...): Option[TypeB]
}

聚合SimpleTypeA和TypeB

trait AggregatedTypeAService {
   def select(...): List[TypeA] //List[AggregatedTypeA]
}

示例impl(使用Google Guice)

class AggregatedTypeAServiceImpl @Inject()(
  typeADAOService: TypeADAOService, 
  typeBDAOService: TypeBDAOService
) extends AggregatedTypeAService {
   def select(...) = typeADAOService.select(...).map(simpleA => 
     AggregatedTypeA(simpleA, typeBDAOService.lookup(...)))
}