db4o_8.0对象数据库官方文档翻译_学习笔记四
緊接上篇:db4o_8.0對象數(shù)據(jù)庫官方文檔翻譯_學(xué)習(xí)筆記三
4.?Querying(查詢)
db4o?supplies?three?querying?systems,?Query-By-Example?(QBE)?Native?Queries?(NQ),?and?the?SODA?API.?In?the?previous?chapter,?you?were?briefly?introduced?to?Query?By?Example(QBE).
Query-By-Example?(QBE)?is?appropriate?as?a?quick?start?for?users?who?are?still?acclimating?to?storing?and?retrieving?objects?with?db4o.
Native?Queries?(NQ)?are?the?main?db4o?query?interface,?recommended?for?general?use.
SODA?is?the?underlying?internal?API.?It?is?provided?for?backward?compatibility?and?it?can?be?useful?for?dynamic?generation?of?queries,?where?NQ?are?too?strongly?typed.
db4o支持三種查詢系統(tǒng):樣本查詢(Query-By-Example,通??s寫為QBE),原生查詢(Native?Queries,縮寫為NQ)和SODA?API。在前面的章節(jié)中,我們概括性地介紹了樣本查詢。
樣本查詢(Query-By-Example)學(xué)習(xí)起來更加快速,對于剛開始學(xué)習(xí)db4o存取對象的用戶非常有效。相對來說,更容易理解吧。
原生查詢(NQ)是db4o主要的常用查詢接口。
SODA是底層的內(nèi)部API。它提供了向后兼容性,并能用于查詢的動態(tài)生成,而使用NQ來完成相同功能卻需要過多的編寫工作。
?
4.1.?Query?by?Example?(QBE)
When?using?Query?By?Example?(QBE)?you?provide?db4o?with?a?template?object.?db4o?will?return?all?of?the?objects?which?match?all?non-default?field?values.?This?is?done?via?reflecting?all?of?the?fields?and?building?a?query?expression?where?all?non-default-value?fields?are?combined?with?AND?expressions.
Here's?an?example?from?the?previous?chapter:
在使用QBE時,你需要提供給db4o一個模板對象。db4o將返回所有匹配此模板的無默認(rèn)字段值(non-default?field?values)的對象。這些工作是通過反射所有字段、創(chuàng)建查詢表達(dá)式來完成的,在查詢表達(dá)式中所有的無默認(rèn)值字段都被AND表達(dá)式連接在一起。下面提供了上一章中的示例:
?
//?retrievePilotByName
Pilot?proto?=?new?Pilot("Michael?Schumacher",?0);
ObjectSet?result?=?db.queryByExample(proto);
listResult(result);
?
Querying?this?way?has?some?obvious?limitations:
-?db4o?must?reflect?all?members?of?your?example?object.
-?You?cannot?perform?advanced?query?expressions.?(AND,?OR,?NOT,?etc.)
-?You?cannot?constrain?on?values?like?0?(integers),?""?(empty?strings),?or?nulls?(reference?types)?because?they?would?be?interpreted?as?unconstrained.
-?You?need?to?be?able?to?create?objects?without?initialized?fields.?That?means?you?can?not?initialize?fields?where?they?are?declared.?You?can?not?enforce?contracts?that?objects?of?a?class?are?only?allowed?in?a?well-defined?initialized?state.
-?You?need?a?constructor?to?create?objects?without?initialized?fields.?
To?get?around?all?of?these?constraints,?db4o?provides?the?Native?Query?(NQ)?system.
?
使用此方式查詢存在著一些明顯的局限性:
-?db4o必須反射所有樣本對象的成員。
-?你不能執(zhí)行高級的查詢表達(dá)式。(AND,OR,NOT等)
-?你不能針對象0(整數(shù))這樣的字段值、""(空白字符串)或者null(引用類型)進(jìn)行約束限制。因為它們都將被解釋為不受約束限制的。
-?你必需能夠使用無初始化字段的方式來創(chuàng)建對象,這意味著你不能在字段聲明時對其進(jìn)行初始化。最難的是,你不能強(qiáng)行約定某個類的對象只能處于這種定義良好的初始化狀態(tài)。
-?你需要一個沒有任何初始化字段的構(gòu)造函數(shù)來創(chuàng)建對象。
為了繞過這些約束,db4o提供了原生查詢(NQ)系統(tǒng)。
?
4.2.?Native?Queries(原生查詢)
Wouldn't?it?be?nice?to?pose?queries?in?the?programming?language?that?you?are?using??Wouldn't?it?be?nice?if?all?your?query?code?was?100%?typesafe,?100%?compile-time?checked?and?100%?refactorable?
Wouldn't?it?be?nice?if?the?full?power?of?object-orientation?could?be?used?by?calling?methods?from?within?queries??Enter?Native?Queries.
Native?queries?are?the?main?db4o?query?interface?and?they?are?the?recommended?way?to?query?databases?from?your?application.?Because?native?queries?simply?use?the?semantics?of?your?programming?language,?they?are?perfectly?standardized?and?a?safe?choice?for?the?future.
Native?Queries?are?available?for?all?platforms?supported?by?db4o.
在你正使用的編程語言中放置查詢,這難道不好嗎?如果你的查詢代碼100%的類型安全、100%在編譯時檢查、100%可重構(gòu),這難道不妙嗎?如果所有面向?qū)ο蟮膬?yōu)勢都能被用于在查詢中調(diào)用方法,這不是很好嗎?如果你正希望這樣,那么請使用原生查詢。
原生查詢是db4o的主要查詢接口,它是查詢數(shù)據(jù)庫的推薦方式。由于原生查詢簡單地使用了編程語言的語法,因此它是非常標(biāo)準(zhǔn)化的,并且是一種面向未來的安全選擇。
原生查詢在所有db4o支持的平臺下均可用。
?
4.2.1.?Concept
The?concept?of?native?queries?is?taken?from?the?following?two?papers:
原生查詢的概念出自下面的兩篇文章:
?
-?Cook/Rosenberger,?Native?Queries?for?Persistent?Objects,?A?Design?White?Paper
-?Cook/Rai,?Safe?Query?Objects:?Statically?Typed?Objects?as?Remotely?Executable?Queries
?
4.2.2.?Principle(原則)
Native?Queries?provide?the?ability?to?run?one?or?more?lines?of?code?against?all?instances?of?a?class.Native?query?expressions?should?return?true?to?mark?specific?instances?as?part?of?the?result?set.?db4o?will?attempt?to?optimize?native?query?expressions?and?run?them?against?indexes?and?without?instantiating?actual?objects,?where?this?is?possible.
原生查詢具備根據(jù)某個類的所有實例來運(yùn)行一行或是多行代碼的能力。原生查詢表達(dá)式返回true來表示結(jié)果集中存在著某些特定實例。db4o將嘗試優(yōu)化原生查詢表達(dá)式,并依靠索引運(yùn)行表達(dá)式,而無需實例化實際的對象。
?
4.2.3.?Simple?Example(簡單實例講解)
Let's?look?at?how?a?simple?native?query?will?look?like?in?some?of?the?programming?languages?and?dialects?that?db4o?supports:
讓我們看以下的簡單原生查詢示例,它看起來酷似某些編程語言和db4o支持的方言(dialects)。
?
C#?.NET
IList?<Pilot>?pilots?=?db.Query?<Pilot>?(delegate(Pilot?pilot)?{
return?pilot.Points?==?100;
});
?
Java?JDK?5
List?<Pilot>?pilots?=?db.query(new?Predicate<Pilot>()?{
public?boolean?match(Pilot?pilot)?{
return?pilot.getPoints()?==?100;
}
});
Public?Class?PilotHundredPoints
Inherits?Predicate
Public?Function?Match?(pilot?As?Pilot)?as?Boolean
If?pilot.Points?=?100?Then
Return?True
Else
Return?False
End?Function
End?Class
A?side?note?on?the?above?syntax:
For?all?dialects?without?support?for?generics,?Native?Queries?work?by?convention.?A?class?that?extends?the?com.db4o.Predicate?class?is?expected?to?have?a?boolean?#match()?method?with?one?parameter?to?describe?the?class?extent:
請注意在上面的語法中:對于所有不支持類屬的方言,NQ遵守約定工作。某個擴(kuò)展自com.db4o.Predicate的類需要有一個boolean?#match()方法,此方法接受一個描述類范圍的參數(shù):
?
boolean?match(Pilot?candidate);
?
When?using?native?queries,?don't?forget?that?modern?integrated?development?environments?(IDEs)?can?do?all?the?typing?work?around?the?native?query?expression?for?you,?if?you?use?templates?and?autocompletion.
Here?is?how?to?configure?a?Native?Query?template?with?Eclipse?3.1:
From?the?menu,?choose?Window?+?Preferences?+?Java?+?Editor?+?Templates?+?New
As?the?name?type?"nq".?Make?sure?that?"java"?is?selected?as?the?context?on?the?right.?Paste?the?following?into?the?pattern?field:
在使用NQ時,不要忘記如果你使用模板和自動完成技術(shù)的話,可用現(xiàn)代化集成開發(fā)環(huán)境(IDEs)來幫你完成所有原生表達(dá)式相關(guān)的代碼錄入工作。
下面是如何在Eclipse3.1中配置原生查詢模板:
從菜單中選擇Window->Preferences->Java->Editor->Templates->New。
我們可用將它起名為"nq"。確認(rèn)你已經(jīng)在右側(cè)的上下文(context)中選擇了"java"。粘貼下列代碼到模板輸入域:
?
List?<${extent}>?list?=?db.query(new?Predicate?<${extent}>?()?{
public?boolean?match(${extent}?candidate){
return?true;
??}
});
Now?you?can?create?a?native?query?with?three?keys:?n?+?q?+?Control-Space.
Similar?features?are?available?in?most?modern?IDEs.
現(xiàn)在,你就能夠使用n+q+Control-Space這三個組合鍵來創(chuàng)建原生查詢了。在大多數(shù)IDE中都有類似的特性。
?
?
4.2.4.?Advanced?Example
For?complex?queries,?the?native?syntax?is?very?precise?and?quick?to?write.?Let's?compare?to?a?SODA?query?that?finds?all?pilots?with?a?given?name?or?a?score?within?a?given?range:
為了進(jìn)行復(fù)雜的查詢,原生語法是非常精確并且書寫快捷的。讓我們將NQ和SODA查詢進(jìn)行一下比較,查詢目標(biāo)是發(fā)現(xiàn)所有匹配給定名字或者成績在指定范圍中的pilot(飛行員):
//?storePilots
db.store(new?Pilot("Michael?Schumacher",100));
db.store(new?Pilot("Rubens?Barrichello",99));
?
//?retrieveComplexSODA
Query?query=db.query();
query.constrain(Pilot.class);
Query?pointQuery=query.descend("points");
query.descend("name").constrain("Rubens?Barrichello")
.or(pointQuery.constrain(99).greater()
.and(pointQuery.constrain(199).smaller()));
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
2
Michael?Schumacher/100
Rubens?Barrichello/99
?
Here?is?how?the?same?query?will?look?like?with?native?query?syntax,?fully?accessible?to?autocompletion,?refactoring?and?other?IDE?features,?fully?checked?at?compile?time:
下面的示例展示了如何同一個查詢在不同語言中使用原生查詢語法的相似性,它們完全可以使用自動完成功能、重構(gòu)和其他IDE特性,并在編譯時作檢查:
?
C#?.NET?2.0
IList?<Pilot>?result?=?db.Query<Pilot>?(delegate(Pilot?pilot)?{
return?pilot.Points?>?99
&&?pilot.Points?<?199
||?pilot.Name?==?"Rubens?Barrichello";
});
?
Java?JDK?5
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");
}
});
?
4.2.5.?Arbitrary?Code(任意代碼)
Basically?that's?all?there?is?to?know?about?native?queries?to?be?able?to?use?them?efficiently.?In?principle?you?can?run?arbitrary?code?as?native?queries,?you?just?have?to?be?very?careful?with?side?effects?-especially?those?that?might?affect?persistent?objects.
Let's?run?an?example?that?involves?some?more?of?the?language?features?available.
基本上,這就是NQ之所以能夠被高效使用的原因。原則上,你可以將任意代碼作為NQ來運(yùn)行,但你需要非常小心某些方面的影響-尤其是那些可能對持久化對象發(fā)生作用的影響。讓我們運(yùn)行一個示例來調(diào)用更多可用的語言特性:
?
//?retrieveArbitraryCodeNQ
final?int[]?points={1,100};
List<Pilot>?result=db.query(new?Predicate<Pilot>()?{
public?boolean?match(Pilot?pilot)?{
for?(int?point?:?points)?{
if?(pilot.getPoints()?==?point)?{
return?true;
}
}
return?pilot.getName().startsWith("Rubens");
}
});
listResult(result);
?
OUTPUT:
2
Michael?Schumacher/100
Rubens?Barrichello/99
?
4.2.6.?Native?Query?Performance??(原生查詢的性能)
??One?drawback?of?native?queries?has?to?be?pointed?out:?Under?the?hood?db4o?tries?to?analyze?native?queries?to?convert?them?to?SODA.?This?is?not?possible?for?all?queries.?For?some?queries?it?is?very?difficult?to?analyze?the?flowgraph.?In?this?case?db4o?will?have?to?instantiate?some?of?the?persistent?objects?to?actually?run?the?native?query?code.?db4o?will?try?to?analyze?parts?of?native?query?expressions?to?keep?object?instantiation?to?the?minimum.
??The?development?of?the?native?query?optimization?processor?will?be?an?ongoing?process?in?a?close?dialog?with?the?db4o?community.?Feel?free?to?contribute?your?results?and?your?needs?by?providing?feedback?to?our?db4o?forums(Forums?are?accessible?through?free?db4o?membership?).
??The?current?state?of?the?query?optimization?process?is?detailed?in?the?chapter?on?Native?Query?Optimization?With?the?current?implementation,?all?above?examples?will?run?optimized,?except?for?the?"Arbitrary?Code"?example?-?we?are?working?on?it.
???這里將指出原生查詢的一個缺點:在內(nèi)部,db4o嘗試分析原生查詢并將其轉(zhuǎn)換為SODA。這并不適用于所有的查詢。對于一些查詢來講,分析流動圖表(flowgraph)是非常困難的。在這種情況下,db4o將不得不實例化一些持久化對象來真正地執(zhí)行原生查詢代碼。db4o會嘗試分析原生查詢表達(dá)式的組成部分,來保持對象實例化的最小化。
???原生查詢優(yōu)化處理器的開發(fā)將是一個持續(xù)不斷地與db4o社區(qū)進(jìn)行親密對話的過程。開發(fā)者可以自愿捐獻(xiàn)開發(fā)成果并通過提交反饋給我們db4o論壇的方式貢獻(xiàn)需求。
???查詢優(yōu)化過程當(dāng)前的狀況在原生查詢優(yōu)化一章中進(jìn)行詳細(xì)描述。?通過使用目前的查詢優(yōu)化器,上面所有的示例都能夠被優(yōu)化運(yùn)行,除了在"任意代碼"中的示例-?我們正在解決此問題。
?
4.2.7.?Full?source(所有代碼)
package?com.db4odoc.f1.chapter1;
import?com.db4o.Db4oEmbedded;
import?com.db4o.ObjectContainer;
import?com.db4o.ObjectSet;
import?com.db4o.query.Predicate;
import?com.db4o.query.Query;
import?com.db4odoc.f1.Util;
import?java.util.List;
public?class?NQExample?extends?Util?{
final?static?String?DB4OFILENAME?=
System.getProperty("user.home")?+?"/formula1.db4o";
public?static?void?main(String[]?args)?{
ObjectContainer?db=Db4oEmbedded.openFile(Db4oEmbedded
.newConfiguration(),?DB4OFILENAME);
try?{
storePilots(db);
retrieveComplexSODA(db);
retrieveComplexNQ(db);
retrieveArbitraryCodeNQ(db);
clearDatabase(db);
}
finally?{
db.close();
}
}
public?static?void?storePilots(ObjectContainer?db)?{
db.store(new?Pilot("Michael?Schumacher",100));
db.store(new?Pilot("Rubens?Barrichello",99));
}
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(99).greater()
.and(pointQuery.constrain(199).smaller()));
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveComplexNQ(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");
}
});
listResult(result);
}
public?static?void?retrieveArbitraryCodeNQ(ObjectContainer?db)?{
final?int[]?points={1,100};
List<Pilot>?result=db.query(new?Predicate<Pilot>()?{
public?boolean?match(Pilot?pilot)?{
for?(int?point?:?points)?{
if?(pilot.getPoints()?==?point)?{
return?true;
}
}
return?pilot.getName().startsWith("Rubens");
}
});
listResult(result);
}
public?static?void?clearDatabase(ObjectContainer?db)?{
ObjectSet?result=db.queryByExample(Pilot.class);
while(result.hasNext())?{
db.delete(result.next());
}
}
}
?
4.3.?SODA?Query?API(SODA查詢API)
??The?SODA?query?API?is?db4o's?low?level?querying?API,?allowing?direct?access?to?nodes?of?query?graphs.?Since?SODA?uses?strings?to?identify?fields,?it?is?neither?perfectly?typesafe?nor?compile-time?checked?and?it?also?is?quite?verbose?to?write.
??For?most?applications?Native?Queries?will?be?the?better?querying?interface.?However?there?can?be?applications?where?dynamic?generation?of?queries?is?required,?that's?why?SODA?is?explained?here.
??SODA查詢API是db4o的低級查詢API,它允許直接訪問查詢圖表(query?graphs)的節(jié)點。由于SODA使用字符串標(biāo)識字段,因此它并不是非常類型安全的,也不是編譯時可檢查的,并且編寫的代碼冗長。
??對于大多數(shù)應(yīng)用來講,原生查詢將是更好的查詢接口。但是,由于存在著需要動態(tài)生成查詢的應(yīng)用,這便是我們?yōu)槭裁丛谶@里解釋SODA的原因。
?
?
4.3.1.?Simple?queries(簡單查詢)
???Let's?see?how?our?familiar?QBE?queries?are?expressed?with?SODA.?A?new?Query?object?is?created?through?the?#query()?method?of?the?ObjectContainer?and?we?can?add?Constraint?instances?to?it.?To?find?all?Pilot?instances,?we?constrain?the?query?with?the?Pilot?class?object.
??讓我們看一下我們熟知的QBE查詢是如何用SODA表示的。一個新的Query對象通過ObjectContainer的#query()方法創(chuàng)建,我們可用在其上添加Constraint類實例。為了找到所有的Pilot實例,我們對Pilot類對象的查詢進(jìn)行了約束限制。
?
//?retrieveAllPilots
Query?query=db.query();
query.constrain(Pilot.class);
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
2
Michael?Schumacher/100
Rubens?Barrichello/99
??Basically,?we?are?exchanging?our?'real'?prototype?for?a?meta?description?of?the?objects?we'd?like?to?hunt?down:?a?query?graph?made?up?of?query?nodes?and?constraints.?A?query?node?is?a?placeholder?for?a?candidate?object,?a?constraint?decides?whether?to?add?or?exclude?candidates?from?the?result.
??Our?first?simple?graph?looks?like?this.
??基本上,我們正在將"真正的"原型(prototype)交換為我們希望捕捉到的對象元描述(meta?description):一個查詢圖表由多個查詢節(jié)點和約束構(gòu)成。每個查詢節(jié)點都是一個存放候選對象的地方,每個約束則標(biāo)識了是否從結(jié)果集中添加還是排除候選者。
??我們的第一個簡單圖表:
?
??We're?just?asking?any?candidate?object?(here:?any?object?in?the?database)?to?be?of?type?Pilot?to?aggregate?our?result.
??To?retrieve?a?pilot?by?name,?we?have?to?further?constrain?the?candidate?pilots?by?descending?to?their?name?field?and?constraining?this?with?the?respective?candidate?String.
??我們正在尋找Pilot類型的候選對象(在這里是數(shù)據(jù)庫中的任意對象),并將其聚會到我們的查詢結(jié)果中。
??為了通過名字獲取某個pilot,我們將通過向下訪問它們的名字字段、使用特殊的候選字符串來限制其取值的方式進(jìn)一步限定候選對象:
//?retrievePilotByName
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").constrain("Michael?Schumacher");
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
1
Michael?Schumacher/100
?
?What?does?#descend?mean?here??Well,?just?as?we?did?in?our?'real'?prototypes,?we?can?attach?constraints?to?child?members?of?our?candidates.
?"descend"(深層訪問)是什么意思?那就是在我們"真正的"原型中將約束分派給候選對象的子成員
??So?a?candidate?needs?to?be?of?type?Pilot?and?have?a?member?named?'name'?that?is?equal?to?the?given?String?to?be?accepted?for?the?result.Note?that?the?class?constraint?is?not?required:?If?we?left?it?out,?we?would?query?for?all?objects?that?contain?a?'name'?member?with?the?given?value.?In?most?cases?this?will?not?be?the?desired?behavior,?though.
??Finding?a?pilot?by?exact?points?is?analogous.We?just?have?to?cross?the?Java?primitive/object?divide.
??所以,一個候選對象必須是Pilot類型、且具有一個name字段,并且"name"字段值為給定字符串,才能出現(xiàn)在結(jié)果集中。請注意,類約束不是必需的:如果我們不設(shè)置它,那么便會查詢到所有"name"字段值為給定字符串的對象。在多數(shù)情況下,這并不是我們想要的行為。
??通過精確的point值來查詢pilot是與上面相似的。我們跨越Java私有類型(primitive)和對象進(jìn)行劃分。
?
//?retrievePilotByExactPoints
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points").constrain(100);
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
1
Michael?Schumacher/100
?
4.3.2.?Advanced?queries(高級查詢)
??Now?there?are?occasions?when?we?don't?want?to?query?for?exact?field?values,?but?rather?for?value?ranges,?objects?not?containing?given?member?values,?etc.?This?functionality?is?provided?by?the?Constraint?API.
??First,?let's?negate?a?query?to?find?all?pilots?who?are?not?Michael?Schumacher:
??此功能適用于我們不想查詢精確字段值時,而是取值范圍、不包含給定成員值的對象等情況時。它提供了Constraint?API來實現(xiàn)之。
??首先,讓我們編寫一個對名字不是Michael?Schumacher的pilot的查詢:
?
//?retrieveByNegation
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").constrain("Michael?Schumacher").not();
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
1
Rubens?Barrichello/99
?
Where?there?is?negation,?the?other?boolean?operators?can't?be?too?far.
在這種反向查詢時,布爾操作很常見。
?
//?retrieveByConjunction
Query?query=db.query();
query.constrain(Pilot.class);
Constraint?constr=query.descend("name")
.constrain("Michael?Schumacher");
query.descend("points")
.constrain(99).and(constr);
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
0
?
?
//?retrieveByDisjunction
Query?query=db.query();
query.constrain(Pilot.class);
Constraint?constr=query.descend("name")
.constrain("Michael?Schumacher");
query.descend("points")
.constrain(99).or(constr);
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
2
Michael?Schumacher/100
Rubens?Barrichello/99
?
We?can?also?constrain?to?a?comparison?with?a?given?value.
我們也可以添加針對給定值進(jìn)行比較的約束。
?
//?retrieveByComparison
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points")
.constrain(99).greater();
ObjectSet?result=query.execute();
listResult(result);
?
OUTPUT:
1
Michael?Schumacher/100
?
?
The?query?API?also?allows?to?query?for?field?default?values.
這種查詢API還能夠查詢字段默認(rèn)值(注意與QBE方式的差別)。
?
//?retrieveByDefaultFieldValue
Pilot?somebody=new?Pilot("Somebody?else",0);
db.store(somebody);
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points").constrain(0);
ObjectSet?result=query.execute();
listResult(result);
db.delete(somebody);
?
OUTPUT:
1
Somebody?else/0
?
It?is?also?possible?to?have?db4o?sort?the?results.
也可以讓db4o對結(jié)果集進(jìn)行排序。
?
//?retrieveSorted
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").orderAscending();
ObjectSet?result=query.execute();
listResult(result);
query.descend("name").orderDescending();
result=query.execute();
listResult(result);
?
OUTPUT:
2
Michael?Schumacher/100
Rubens?Barrichello/99
2
Rubens?Barrichello/99
Michael?Schumacher/100
?
??All?these?techniques?can?be?combined?arbitrarily,?of?course.?Please?try?it?out.?There?still?may?be?cases?left?where?the?predefined?query?API?constraints?may?not?be?sufficient?-?don't?worry,?you?can?always?let?db4o?run?any?arbitrary?code?that?you?provide?in?an?Evaluation.?Evaluations?will?be?discussed?in?a?later?chapter.
??To?prepare?for?the?next?chapter,?let's?clear?the?database.
??當(dāng)然,以上這些技術(shù)都能夠任意組合使用。請大家自行嘗試。也許預(yù)定義的查詢API約束并不能滿足需要,請不要著急,你可以讓db4o執(zhí)行在Evaluation(評估)中提供的任意代碼。Evaluation將在最后一章中討論。
??為了下一章做準(zhǔn)備,讓我們清空數(shù)據(jù)庫。
?
//?clearDatabase
ObjectSet?result=db.queryByExample(Pilot.class);
while(result.hasNext())?{
db.delete(result.next());
}
?
OUTPUT:
?
4.3.3.?Conclusion(總結(jié))
???Now?you?have?been?provided?with?the?following?alternative?approaches?to?query?db4o?databases:?Query-By-Example,.??net?LINQ,?Native?Queries,?SODA.
Which?one?is?the?best?to?use??Some?hints:
??-?Native?queries?are?targeted?to?be?the?primary?interface?for?db4o,?so?they?should?be?preferred.
??-?With?the?current?state?of?the?db4o?query?optimizer?there?may?be?queries?that?will?execute?faster?in?SODA?style,?so?it?can?be?used?to?tune?applications.?SODA?can?also?be?more?convenient?for?constructing?dynamic?queries?at?runtime.
??-?Query-By-Example?is?nice?for?simple?one-liners,?but?restricted?in?functionality.?If?you?like?this?approach,?use?it?as?long?as?it?suits?your?application's?needs.?
???Of?course?you?can?mix?these?strategies?as?needed.
???We?have?finished?our?walkthrough?and?seen?the?various?ways?db4o?provides?to?pose?queries.?But?our?domain?model?is?not?complex?at?all,?consisting?of?one?class?only.?Let's?have?a?look?at?the?way?db4o?handles?object?associations?in?the?next?chapter?.
???到此為止,你已經(jīng)了解了以下三種查詢db4o數(shù)據(jù)庫的方式:樣本查詢(QBE)、原生查詢(NQ)、SODA。
???哪一種是最好的呢?下面給出了一些提示:
-?原生查詢的目標(biāo)是成為db4o的首要接口,因此它應(yīng)該作為首選。
-?鑒于當(dāng)前原生查詢優(yōu)化器的狀態(tài),某些查詢使用SODA風(fēng)格能夠獲得更快的執(zhí)行速度,因此它被用于對應(yīng)用進(jìn)行優(yōu)化。SODA對于在運(yùn)行時構(gòu)造動態(tài)查詢也是非常方便的。
-?樣本查詢是非常簡單的單行查詢,但在功能上存在局限。如果你喜歡這種方式,并且它能夠滿足你的應(yīng)用要求的話,仍可以使用。
??當(dāng)然,你也可以按需混合上面的風(fēng)格。
??到此為止,我們已經(jīng)完成了關(guān)于查詢的學(xué)習(xí),并且看到了多種db4o提供的查詢。但我們的所定義的類模型一點都不復(fù)雜,僅僅由一個類構(gòu)成。在下一章,我們將看到db4o是如何處理對象關(guān)聯(lián)。
?
4.3.4.?Full?source(所有源代碼)
package?com.db4odoc.f1.chapter1;
import?com.db4o.*;
import?com.db4o.query.Constraint;
import?com.db4o.query.Query;
import?com.db4odoc.f1.*;
public?class?QueryExample?extends?Util?{
final?static?String?DB4OFILENAME?=
System.getProperty("user.home")?+?"/formula1.db4o";
public?static?void?main(String[]?args)?{
ObjectContainer?db=Db4oEmbedded.openFile(Db4oEmbedded
.newConfiguration(),?DB4OFILENAME);
try?{
storeFirstPilot(db);
storeSecondPilot(db);
retrieveAllPilots(db);
retrievePilotByName(db);
retrievePilotByExactPoints(db);
retrieveByNegation(db);
retrieveByConjunction(db);
retrieveByDisjunction(db);
retrieveByComparison(db);
retrieveByDefaultFieldValue(db);
retrieveSorted(db);
clearDatabase(db);
}
finally?{
db.close();
}
}
public?static?void?storeFirstPilot(ObjectContainer?db)?{
Pilot?pilot1=new?Pilot("Michael?Schumacher",100);
db.store(pilot1);
System.out.println("Stored?"+pilot1);
}
public?static?void?storeSecondPilot(ObjectContainer?db)?{
Pilot?pilot2=new?Pilot("Rubens?Barrichello",99);
db.store(pilot2);
System.out.println("Stored?"+pilot2);
}
public?static?void?retrieveAllPilots(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrievePilotByName(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").constrain("Michael?Schumacher");
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrievePilotByExactPoints(
ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points").constrain(100);
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveByNegation(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").constrain("Michael?Schumacher").not();
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveByConjunction(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
Constraint?constr=query.descend("name")
.constrain("Michael?Schumacher");
query.descend("points")
.constrain(99).and(constr);
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveByDisjunction(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
Constraint?constr=query.descend("name")
.constrain("Michael?Schumacher");
query.descend("points")
.constrain(99).or(constr);
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveByComparison(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points")
.constrain(99).greater();
ObjectSet?result=query.execute();
listResult(result);
}
public?static?void?retrieveByDefaultFieldValue(
ObjectContainer?db)?{
Pilot?somebody=new?Pilot("Somebody?else",0);
db.store(somebody);
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("points").constrain(0);
ObjectSet?result=query.execute();
listResult(result);
db.delete(somebody);
}
public?static?void?retrieveSorted(ObjectContainer?db)?{
Query?query=db.query();
query.constrain(Pilot.class);
query.descend("name").orderAscending();
ObjectSet?result=query.execute();
listResult(result);
query.descend("name").orderDescending();
result=query.execute();
listResult(result);
}
public?static?void?clearDatabase(ObjectContainer?db)?{
ObjectSet?result=db.queryByExample(Pilot.class);
while(result.hasNext())?{
db.delete(result.next());
}
???}
}
總結(jié)
以上是生活随笔為你收集整理的db4o_8.0对象数据库官方文档翻译_学习笔记四的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVa 1624 打结(Knots)
- 下一篇: linux cmake编译源码,linu