我有一个案例类,它的一些字段作为选项类型。请考虑以下案例类:
case class TypeA(field1: Int, field2: Option[String], field3: Boolean)
此案例类将由持久层实例化,该层调用数据库表并返回此案例类的实例。 field2的值来自数据库中的另一个表,几乎在所有情况下,返回TypeA的方法都不需要设置field2。通过执行数据库查找返回TypeA后,将设置field2的值。我想在TypeA中使用field2但我不希望将其作为TypeA构造函数的一部分。部分功能,特征浮现在我的脑海中,但由于我是Scala的新手,我正在寻找一些好的做法。有什么建议吗?
答案 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(...)))
}