play 框架引入了一个简单的数据库访问层:anorm。
使用anorm做模型层,代码大致如下:
Scala代码
- case class Dog(id: Pk[Long], name: String, age: String)
- object Dog {
- val simple = get[Pk[Long]]( "dog.id" ) ~ str( "name" ) ~ int( "age" ) map {
- case id ~ name ~ age => Dog(id, name, age)
- }
- def findById(id: Long) = DB.withConnection {
- implicit connection =>
- SQL( "select * from dog where id = {id}" ).on('id -> id).as(Dog.simple.singleOpt)
- }
- def create(dog: Dog) = DB.withConnection {
- implicit connection =>
- val idOpt: Option[Long] = SQL(
- "" "
- insert into dog (name, age)
- values ({name}, {age})
- "" "
- ).on(
- 'name -> dog.name,
- 'age -> dog.age
- ).executeInsert()
- val result = dog.copy(id = Id(idOpt.get))
- result
- }
- def update(id: Long, dog: Dog) = DB.withConnection {
- implicit connection =>
- SQL(
- "" "
- update dog set name = {name}, age = {age} where id = {id}
- "" "
- ).on(
- 'id -> id,
- 'name -> dog.name,
- 'age -> dog.age
- ).executeUpdate()
- }
- }
明显比JPA繁杂,那么,有没有办法封装下anorm,使它更象orm,提供更好的维护性,更快的开发速度?
在scala 2.10中,引入的试验性功能:macro, reflection,或许就是问题的答案(现在只是一个构想,会抽空实现验证下),还是代码为先:
Scala代码
- trait Modal[T] {
- val simple = macro ModalMacroImpl.simple[T]
- def findById(id: Long): Option[T] = macro ModalMacroImpl.find
- def create(o: T) = macro ModalMacroImpl.create
- def update(id: Long, o: T) = macro ModalMacroImpl.update
- def list = macro ModalMacroImpl.list
- }
- object Dog extends Modal[Dog] {
- def findByName(name: String): Option[T] = macro ModalMacroImpl.find
- }
通过Modal及提供的macro,简化了model的定义。
ModalMacroImpl可以通过reflaction实现,并且macro是编译时增强的,不会对性能造成影响。
原文链接: http://www.software8.co/wzjs/