用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解决方案。

相关文章
相关标签/搜索