一直想給ScalaFX找一個合適的持久曾框架,要越方便越好。 java
接觸Scala以前玩的是JavaFX,曾用熟悉的Mybatis寫持久層,JavaFxBean的Properties不能用IDE自動生成用於Mybatis的getter和setter。比方說一個屬性 數據庫
private fianl IntegerProperty age = new SimpleIntegerProperty(this, "age", 20);用Eclipse或IDEA能夠生成以下getter和setter
public IntegerProperty getAge() { return age; } public void setAge(IntegerProperty age) { this.age = age; }然而持久層框架須要的(也就是JavaFxBean的標配)是這樣的getter和setter
public String getName() { return name.get(); } public void setName(String name) { this.name.set(name); } public StringProperty nameProperty() { return name; }本身寫過一個簡單的工具用來生產這樣的getter和setter,但仍嫌麻煩。
(IDEA12.1已經支持生成JavaFX風格的getter和setter了) app
(技術選型中,不喜請略過) 框架
現在轉向ScalaFX,Scala自帶的BeanProperty註解生產的getter和setter也是JavaBean風格的,而IDEA12.1提供的便利也期望不上。因此一直在找替代方案。期間看到了OrientDB,這是一個純Java的嵌入式NoSQL數據庫,我是很看好它的,它甚至還提供了一個直接將JavaBean映射爲Document的object模塊。然而最大的問題是,object模塊是直接映射Field,而不是getter和setter(源碼中彷佛是支持getter和setter的,由於是春節期間看的源碼,再加上用的破筆記本,看不太仔細),同時對final字段會排出在外(而用val聲明的字段剛好是final的)。原本想要改造orientdb-object模塊,但並無特別好的解決方案。 ide
前些天學Play2的過程當中Slick進入了個人視線,真正作到了零配置,也不須要寫SQL。
(說實在的,爲了作一個簡單的查詢,又要寫建表語句,又要寫各類SQL文,而後建立各類JavaBean,還有就是一堆配置文件,啊,簡直要瘋了。最好能省則省啊。) 工具
原本JPA是個好選擇,可是看網上JPA教材的時候第一眼看到了配置文件,我對配置文件那個煩啊(主要是記性很差,沒IDE提示徹底不知道怎麼寫),而後就無論它了。Slick好,沒有配置文件,不須要寫SQL(但須要定義Schema),那麼就它吧。 this
(選型完畢,繼續) scala
首先要聲明一個ScalaFxBean,簡單起見,只定義兩個屬性 code
class Person(_name: String, _age: Int) { def this() = this(null, 0) lazy val name = new StringProperty(this, "name", _name) lazy val age = new IntegerProperty(this, "age", _age) def name_=(v: String) { name() = v } def age_=(v: Int) { age() = v } override def toString = s"name = ${name()}; age = ${age()}" }這種類聲明方式是參照ProJavaFX2中Scala and JavaFX一節。
Slick提供三種方式訪問數據庫(具體請在Slick官網瞭解),這裏用的是叫作Lifted的方式,它其實是將數據看做Tuple,咱們須要將Tuple映射成對象(經過apply和unapply方法) 對象
def apply(name: String, age: Int) = new Person(name, age) def unapply(p: Person) = Option((p.name(), p.age()))而後是定義Schema,我把apply和unapply也整合進來
object Persons extends Table[Person]("persons") { def name = column[String]("name", O.NotNull) def age = column[Int]("age") def * = name ~ age <>(Persons.apply _, Persons.unapply _) def apply(name: String, age: Int) = new Person(name, age) def unapply(p: Person) = Option((p.name(), p.age())) }而後就能夠操做數據了
object UsePerson extends App { val p = new Person("misty", 23) val db = Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") val ddl = Persons.ddl db withSession { ddl.create Persons.insert(p) val q = Query(Persons) q foreach println ddl.drop } }也算是比較簡潔了,但還有個缺點,就是ScalaBean和Schema之間有重複聲明的感受。
其實JPA能夠算是將Schema以註解的方式合併到JavaBean中。明天再試試JPA(若是有精力的話),惋惜沒有Scala的JPA解決方案。