NQ
你不想使用你使用的編程語(yǔ)言來(lái)構(gòu)造查詢條件?它是100%類(lèi)型安全并且100%編譯時(shí)檢查和100%可分解.不想通過(guò)面向?qū)ο蟮?br />原則來(lái)實(shí)現(xiàn)查詢? 來(lái)吧!進(jìn)入NQ
NQ是主要的查詢接口,它被推薦使用在你的應(yīng)用中查詢數(shù)據(jù)庫(kù),因?yàn)樗捎媚闶褂玫木幊陶Z(yǔ)言的語(yǔ)法,它是完美的標(biāo)準(zhǔn),對(duì)于
將來(lái)也是安全的選擇.
NQ支持所有平臺(tái).
觀念
NQ的感念來(lái)自下面的兩篇文章:
Cook/Rosenberger, Native Queries for Persistent Objects, A Design White Paper
Cook/Rai, Safe Query Objects: Statically Typed Objects as Remotely Executable Queries
原則
NQ通過(guò)運(yùn)行一行或者多行代碼而不是一個(gè)對(duì)象的所有實(shí)例.NQ表達(dá)式返回真,標(biāo)記指定的實(shí)例作為查詢的結(jié)果集的一部分,
db4o試圖優(yōu)化NQ表達(dá)式,通過(guò)索引而不是真實(shí)的實(shí)例.
簡(jiǎn)單的例子:
讓我們看看采用db4o所支持的編程語(yǔ)言,用NQ是多么的簡(jiǎn)單.
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;
??? }
}
順便提醒一下上邊的語(yǔ)法:
對(duì)于所有的方言不支持通用類(lèi)型,NQ按照習(xí)慣工作.一個(gè)繼承Predicate類(lèi)的對(duì)象有一個(gè)返回布爾值方法match()或者M(jìn)atch()
這個(gè)方法有一個(gè)參數(shù).
Java: boolean match(Pilot candidate);
當(dāng)你使用NQ時(shí),別忘記用先進(jìn)IDE來(lái)輸入NQ表達(dá)式.如果你使用了模板和自動(dòng)完成功能.
下面是如何在Eclipse3.1中配置:
1.打開(kāi)菜單,選擇 Window + Preferences + Java + Editor + Templates + New
名字為np,確保選擇java在context中,拷貝下面內(nèi)容到Pattern field中:
List <${extent}> list = db.query(new Predicate <${extent}> () {
public boolean match(${extent} candidate){
return true;
}
});
現(xiàn)在,你可以創(chuàng)建NQ查詢通過(guò)n + q + Control-Space
這些簡(jiǎn)單的功能在許多先進(jìn)的IDE是有效的.
深入的例子
對(duì)于復(fù)雜的查詢,NQ語(yǔ)法是非常準(zhǔn)確并且便于很快的書(shū)寫(xiě).讓我們比較SODA查詢給定名字或者給定成績(jī)區(qū)間的pilot.
存儲(chǔ):
NQExample.java: storePilots
public static void storePilots(ObjectContainer db) ...{
?????? db.set(new Pilot("Michael Schumacher",100));
?????? db.set(new Pilot("Rubens Barrichello",99));
??? }
通過(guò)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);
??? }
下面是通過(guò)NQ語(yǔ)法實(shí)現(xiàn)相同的查詢.它是跟容易自動(dòng)完成可分解等其他IDE特性,并且還是運(yùn)行期檢查.
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,原則上,你可以運(yùn)行使用NQ任意隨意的查詢,你僅僅要考慮其他的影響,特別是
可能影響持久化的對(duì)象.
讓我們運(yùn)行一個(gè)例子來(lái)包括更多的有效語(yǔ)言特性:
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 性能
對(duì)于NQ的一個(gè)缺點(diǎn)必須要指出:NO引擎試圖分析NQ表達(dá)式,并把它們轉(zhuǎn)化為SODA,這對(duì)于所有的查詢時(shí)不可能的.對(duì)于某些
查詢,這種分析將是非常困難,如何這樣,db4o將不得不實(shí)例化一些持久對(duì)象來(lái)執(zhí)行NQ代碼.db4o將試圖分析部分NQ表達(dá)式
來(lái)保證對(duì)象實(shí)例盡量的少.
db4o社區(qū)有對(duì)NQ優(yōu)化團(tuán)隊(duì),你可以把你的結(jié)果和反饋給db4o組織。當(dāng)前優(yōu)化細(xì)節(jié)在NQ Optimization 章節(jié)。
對(duì)于當(dāng)前的實(shí)現(xiàn),上面除了隨意的查詢外,其他的都進(jìn)行了優(yōu)化。