2007-08-10
Scala 用函数式编程的方法调用db4o
关键字: scala db4o javadb4o 是一个开源的纯面向对象数据库,同时支持Java和dotNet。使用db4o可以用更加面向对象的方式存储数据,比JPA等通过ORM来协调数据库和对象之间的方案来的更为自然。
那么用函数式编程的眼光来看,应该如何使用db4o这样的库呢?首先我们来看一个db4o的包装类
xml 代码
- package plan.util;
- import com.db4o.query.Query
- abstract class LazyQuery[QInterface, T] (val criteria: List[Query=>Query]) extends Iterable[T] {
- def elements = {
- val init: Query = null
- // 等价于 criteria leftFold init ( query=>query(query=>query) )
- val query = (criteria :\ init)((f, q)=>f(q))
- Db4oUtil.iterate[T](query)
- }
- def factory: List[Query=>Query]=>QInterface
- def constrain(c: Query=>Query) = factory(c :: criteria)
- }
- object Db4oUtil {
- def iterate[T](q: Query) = {
- val set = q.execute()
- new Iterator[T] {
- def hasNext = set.hasNext
- def next = set.next.asInstanceOf[T]
- }
- }
- }
看一个实际的例子,People和AutoInfo是POJO,People有一个指向AutoInfo的List。通过继承LazyQuery的Peoples可以很容易做一些查询、filter、以及复杂的操作。由于是functional的(所有的constrain都是query=>query的函数),所以各个查询条件可以互相组合,非常方便
xml 代码
- package plan;
- import plan.util.Db4oUtil
- import plan.util.LazyQuery
- import com.db4o.Db4o
- import com.db4o.ObjectContainer
- import com.db4o.query.Query
- import scala.reflect.BeanProperty
- class People {
- @BeanProperty
- var id: int =_
- @BeanProperty
- var name: String =_
- @BeanProperty
- var address: String =_
- @BeanProperty
- var autoInfoList: java.util.List = new java.util.ArrayList
- def addAutoInfo(autoInfo: AutoInfo) = {
- autoInfoList.add(autoInfo)
- }
- def autoCount = autoInfoList size
- }
- class AutoInfo {
- @BeanProperty
- var id: int = _
- @BeanProperty
- var name: String = _
- @BeanProperty
- var owner: People = _
- }
- class Peoples(criteria: List[Query=>Query]) extends LazyQuery[Peoples, People](criteria) {
- override def factory = new Peoples(_)
- def withAuto() = {
- constrain { q=>
- q.descend("autoInfoList")
- q
- }
- }
- def totalAuto = (this.map(_.autoCount) :\ 0)( (f,g) => f + g )
- }
- object Db4oTest {
- var db: ObjectContainer = _
- def initData() = {
- val peo = new People
- peo.address = "北京"
- peo.name = "Chris"
- var auInfo = new AutoInfo
- auInfo.name = "雪铁龙"
- auInfo.owner = peo
- peo.addAutoInfo(auInfo)
- db.set(peo)
- val peo1 = new People
- peo1.address = "上海"
- peo1.name = "Louis"
- db.set(peo1)
- }
- private def query(klass: Class) = {
- val q = db.query()
- q.constrain(klass)
- q
- }
- def main(args: Array[String]) = {
- db = Db4o.openFile("auto.yap")
- try {
- //initData
- val peoples = new Peoples(List(q=>query(classOf[People])))
- // get total car all people have
- println( peoples.totalAuto )
- // lazy query all people
- for (peo <- peoples.elements) {
- println( peo.name )
- }
- // lazy query all people with autoinfo
- for (peo <- peoples.withAuto.elements) {
- println( peo.name )
- }
- }finally{
- db.close();
- }
- }
- }
- 浏览: 10121 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
在scala里调用Hibernate ...
是在JVM上的一种函数式语言,和java可以互相调用,http://www.sc ...
-- by fakechris -
scala学习笔记(1)
用了 Java 的实现描述语法我知道;不过利用了虚类,确实有点新意啊。
-- by Lich_Ray -
scala学习笔记(1)
实际上String=>Unit 是一个scala的trait,相当于java的接 ...
-- by fakechris -
scala学习笔记(1)
var fn = new ( String=>Unit ) { def ap ...
-- by Lich_Ray -
python的小工具,把hibern ...
嗯,输入太工整了正则表达式也就能处理这么工整的代码了,格式比较乱的还是要上ast ...
-- by fakechris






评论排行榜