一直想给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解决方案。