正如对该问题的评论所述,我取消了Enums
直接从MySQL
数据库或JSON
. 显然,这些字段现在VARCHAR
是数据库中的 simple ,我将验证逻辑移到了我的Scala
代码中。由于我单独执行验证,因此case class
我用来保存从读取的数据MySQL
或JSON
不再具有任何Enum.Value
类型字段的 es。
Enums
我会说直接在数据库中会更有意义。但由于缺乏简单的解决方案,我选择了这种解决方法。这仍然是一个悬而未决的问题,一旦找到解决方案,我将更新答案。
来到我问题的另一部分
可以使用相同的案例类来解析 ScalikeJdbc 和 ScalaJson 中的数据,还是它们需要不同?
是的
我用 s 创建了case class
es,我可以在 .s 和 .s中companion object
使用它们进行自动转换。我正在发布一个完整的以及它的服务这个双重目的。ScalikeJdbc
ScalaJson
case class
companion object
注意:此代码示例来自一个旨在将表格从一个位置移动到另一个位置的框架。[实际生产代码] MySQL
案例类:
case class Table(dbId: Option[Int] = None,
id: Option[Int] = None,
name: String,
shouldCopy: Option[Boolean] = None,
lastUpdated: Option[DateTime] = None
)
伴侣对象:
object Table {
private def mapResultToTable(rs: WrappedResultSet): Table = Table(
dbId = rs.intOpt("db_id"),
id = rs.intOpt("id"),
name = rs.string("name"),
shouldCopy = rs.booleanOpt("should_copy"),
lastUpdated = rs.dateTimeOpt("last_updated").flatMap { zonedDateTime: ZonedDateTime =>
Some(DateTime.parse(zonedDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)).plusMinutes(330))
}
)
def getTables(db: Db)(implicit session: DBSession): Seq[Table] = {
sql"""
SELECT
*
FROM
db_name.tables
WHERE
db_id = ${db.id} AND
should_copy = b'1'
ORDER BY
name ASC
""".
map(mapResultToTable).
list().
apply()
}
// for Play-Json [Scala-Json]
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")
implicit val dateTimeWriter = JodaWrites.jodaDateWrites("dd/MM/yyyy HH:mm:ss")
implicit val reads = Json.reads[Table]
implicit val writes = Json.writes[Table]
}
以下是对代码特定部分的解释:
def mapResultToTable(rs: WrappedResultSet)
此方法读取数据库查询的结果集并构建一个object
case class
def getTables(db: Db)
此方法查询MySQL
数据库正在使用ScalikeJdbc
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")
implicit val dateTimeJsReader = JodaReads.jodaDateReads("yyyyMMddHHmmss")
这些是用于参数的Joda
DateTime
读写转换器(由 使用ScalaJson
)Joda
DateTime
case class
implicit val reads = Json.reads[Table]
implicit val writes = Json.writes[Table]
这些是给定的读写转换器case class
最后,这是从 Json 文件中读取此案例类数据的代码片段
val tableOpt: Option[Table] = try {
val rawJsonString: String = Source.fromFile("path/to/file/fileName.json").mkString
Some(Json.parse(rawJsonString).as[Table])
} catch {
case ex: Throwable =>
println(s"Exception while reading Json file: '$ex'")
None
}
对像我这样的菜鸟的最后一条建议:除非您对ScalaJson
(并且JSON
通常会解析)感到满意,否则请避免使用Json.parse(jsonString).asOpt[T]
方法(上面的代码片段使用.as[T]
方法)以克服像这样的细微错误。
编辑-1
ScalikeJdbc 是否支持解析像 ScalaJson 这样的枚举值?
获得Enum.Value
真的无关ScalikeJdbc
:一旦你拥有了String
,转换成有多难Enum.Value
?
这是一个小例子:
// Enum
object CloudProvider extends Enumeration {
val AWS: Value = Value("aws")
val MicrosoftAzure: Value = Value("microsoft-azure")
val GoogleCloud: Value = Value("google-cloud")
}
// Case Class
case class SiteInfo(website: String, provider: CloudProvider.Value)
// Mapper method
def mapResult(rs: WrappedResultSet): SiteInfo = {
val website: String = rs.string("website")
val provider: CloudProvider.Value = CloudProvider.values.
find(_.toString == rs.string("provider")).
getOrElse(CloudProvider.AWS)
SiteInfo(website, provider)
}
很难理解为什么当它就在我面前时我看不到答案:(mapResult
方法)
..一般来说,使用枚举是个好主意吗..
是的,一点没错
拥有Enum
类型的全部意义在于限制变量可以取值的范围。除了Enum
.
同样,一旦您对使用的语言/库有足够的了解(当时我不太了解Scala
)ScalikeJdbc
,使用绝对没有开销(从编码的角度来看)Enum
;事实上,它们使代码更加清晰。不用说,即使从性能的角度来看,使用Enum
s 也比 using 好得多String
。