用Slick持久化ScalaFxBean

一直想給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解決方案。

相關文章
相關標籤/搜索