1. scala 反射,得到全部 field namejava
能够直接从 case class 得到 field 而没必要建立实例 (get fields of a class without an instance)mysql
def extractFieldNames[T<:Product:Manifest] = {
implicitly[Manifest[T]].erasure.getDeclaredFields.map(_.getName)
} sql
case class Person(name:String, age:Int)
scala> extractFieldNames[Person]
res4: Array[java.lang.String] = Array(name, age)json
2. Joda time app
joda time 据称是 jdk1.8 之前最好的时间系统,我以为 joda time 的确比 java 自带的时间系统好用。java 自带的时间系统须要花很大的功夫来处理格式的问题,time 与 calendar 也没结合到一块儿,印象中,每次处理时间问题起码要写三行代码。因用 asyn mysql db 引入 joda time,但在 joda time 与 json 的序列化和非序列化时遇到了问题。less
val res = Tag(new LocalDate, "id", "tag")ide
val names = res.getClass.getDeclaredFields.map(field => field.getName)函数
val mapping = names.map(name => (name -> row(name))).toMapidea
val str = JacksonUtils.objectMapper.writeValueAsString(mapping)spa
val ins = JacksonUtils.objectMapper.readValue(str, classOf[Tag])
joda time 的 toString 并不简单,好比LocalDate类型的 "2014-05-05" 转化到 json 后会有很长一串数据,再从 json 转到 joda time,jackson 报错,序列化有问题了。
在 jackson 2.0 (也就是 fastxml)之后,处理 joda time 有一种很简单的作法,就是直接注册 joda time module 到 jackson mapper
val objectMapper = new ObjectMapper()
objectMapper.registerModule(DefaultScalaModule)
objectMapper.registerModule(new JodaModule)
3. Jackson 注册 Module 用于序列化
同时也了解到,objectMapper 能够一次注册多个 module,这种可拔插的设计用起来真的很舒心。
在第一段代码中,用到了 scala 反射机制。其实这段代码的主要目标是编写一个简单的数据转换器,从 mysql resultSet 转到 case class。转换的步骤是这样的:
虽然说实现了转换,可是代码很是的 ugly。首先,咱们要用到的是 case class instance 而不是 case class 自己,这意味着必须建立一个 instance,这个 instance 除了提供 field 信息之外就没用了,其次,建立 instance 自己须要了解 case class 的定义,由于须要写入到构造函数中,而上面转换器的目标就在于shapeless,在于通用,这不得不让咱们为 case class 编写不少的 default value。再一个,还用到了 jackson,先到 string,再转回去,很是麻烦。
注意到几个问题: