首页 文章

案例类中的Scala Option类型

提问于
浏览
2

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

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

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

3 回答

  • 0

    如果我很了解您的情况,您可以执行以下操作:

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

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

  • 3

    这会实现你想要的吗?

    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)
    
  • 1

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

    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 - 基本特征,将有不同的impls

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

相关问题