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,再轉回去,很是麻煩。
注意到幾個問題: