翻译DB4O参考——Query(四)

翻译DB4O参考——Query(四)

NQ

你不想使用你使用的编程语言来构造查询条件?它是100%类型安全并且100%编译时检查和100%可分解.不想通过面向对象的
原则来实现查询? 来吧!进入NQ
NQ是主要的查询接口,它被推荐使用在你的应用中查询数据库,因为它采用你使用的编程语言的语法,它是完美的标准,对于
将来也是安全的选择.
NQ支持所有平台.

观念

NQ的感念来自下面的两篇文章:
Cook/Rosenberger, Native Queries for Persistent Objects, A Design White Paper
Cook/Rai, Safe Query Objects: Statically Typed Objects as Remotely Executable Queries

原则

NQ通过运行一行或者多行代码而不是一个对象的所有实例.NQ表达式返回真,标记指定的实例作为查询的结果集的一部分,
db4o试图优化NQ表达式,通过索引而不是真实的实例.
简单的例子:
让我们看看采用db4o所支持的编程语言,用NQ是多么的简单.

Java5:

PrimitiveExample.java: primitiveQuery
public static void primitiveQuery(ObjectContainer db)...{
    List pilots = db.query(new Predicate() ...{
        public boolean match(Pilot pilot) ...{
            return pilot.getPoints() == 100;
        }
    });
  }
Java1.2-1.4:

NQExample.java: primitiveQuery
public static void primitiveQuery(ObjectContainer db)...{
      List <Pilot> pilots = db.query(new Predicate<Pilot>() ...{
          public boolean match(Pilot pilot) ...{
              return pilot.getPoints() == 100;
          }
      }); 
    }

Java1.1:

PrimitiveExample.java: primitiveQuery1
public static void primitiveQuery1(ObjectContainer db)...{
    List pilots = db.query(new PilotHundredPoints());
  }
PilotHundredPoints.java
/**//* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */
import com.db4o.query.Predicate;

public class PilotHundredPoints extends Predicate ...{
    public boolean match(Pilot pilot) ...{
        return pilot.getPoints() == 100;
    }
}

顺便提醒一下上边的语法:
对于所有的方言不支持通用类型,NQ按照习惯工作.一个继承Predicate类的对象有一个返回布尔值方法match()或者Match()
这个方法有一个参数.
Java: boolean match(Pilot candidate);
当你使用NQ时,别忘记用先进IDE来输入NQ表达式.如果你使用了模板和自动完成功能.
下面是如何在Eclipse3.1中配置:
1.打开菜单,选择 Window + Preferences + Java + Editor + Templates + New
名字为np,确保选择java在context中,拷贝下面内容到Pattern field中:
List <${extent}> list = db.query(new Predicate <${extent}> () {
public boolean match(${extent} candidate){
return true;
}
});
现在,你可以创建NQ查询通过n + q + Control-Space
这些简单的功能在许多先进的IDE是有效的.

深入的例子


对于复杂的查询,NQ语法是非常准确并且便于很快的书写.让我们比较SODA查询给定名字或者给定成绩区间的pilot.
存储:
NQExample.java: storePilots
public static void storePilots(ObjectContainer db) ...{
       db.set(new Pilot("Michael Schumacher",100));
       db.set(new Pilot("Rubens Barrichello",99));
    }
通过SODA查询:
NQExample.java: retrieveComplexSODA
public static void retrieveComplexSODA(ObjectContainer db) ...{
        Query query=db.query();
        query.constrain(Pilot.class);
        Query pointQuery=query.descend("points");
        query.descend("name").constrain("Rubens Barrichello")
          .or(pointQuery.constrain(new Integer(99)).greater()
              .and(pointQuery.constrain(new Integer(199)).smaller()));
        ObjectSet result=query.execute();
        listResult(result);
    }
下面是通过NQ语法实现相同的查询.它是跟容易自动完成可分解等其他IDE特性,并且还是运行期检查.
NQExample.java: advancedQuery
public static void advancedQuery(ObjectContainer db)...{
      List <Pilot> result = db.query(new Predicate<Pilot>() ...{
          public boolean match(Pilot pilot) ...{
              return pilot.getPoints() > 99
                  && pilot.getPoints() < 199
                 || pilot.getName().equals("Rubens Barrichello");
         }
      }); 
   }

随意的查询 .

基本而言,你可以有效地使用NQ,原则上,你可以运行使用NQ任意随意的查询,你仅仅要考虑其他的影响,特别是
可能影响持久化的对象.
让我们运行一个例子来包括更多的有效语言特性:
NQExample.java: retrieveArbitraryCodeNQ
public static void retrieveArbitraryCodeNQ(ObjectContainer db) ...{
      final int[] points=...{1,100};
        ObjectSet result=db.query(new Predicate<Pilot>() ...{
          public boolean match(Pilot pilot) ...{
            for(int i=0;i<points.length;i++) ...{
              if(pilot.getPoints()==points[i]) ...{
                return true;
              }
            }
            return pilot.getName().startsWith("Rubens");
      }
        });
        listResult(result);
    }

NQ 性能

对于NQ的一个缺点必须要指出:NO引擎试图分析NQ表达式,并把它们转化为SODA,这对于所有的查询时不可能的.对于某些
查询,这种分析将是非常困难,如何这样,db4o将不得不实例化一些持久对象来执行NQ代码.db4o将试图分析部分NQ表达式
来保证对象实例尽量的少.
db4o社区有对NQ优化团队,你可以把你的结果和反馈给db4o组织。当前优化细节在NQ Optimization 章节。
对于当前的实现,上面除了随意的查询外,其他的都进行了优化。

你可能感兴趣的:(翻译DB4O参考——Query(四))