SODA Query API
SODA是db4o底層查詢接口,它允許你直接使用查詢圖的節點。由于SODA使用字符串來區分屬性,所以沒有很好類型安全
機制和編譯時檢測,同時,它的書寫比較冗長。對于大多數應用,NQ是比較好的查詢接口。然而,如果一個應用需要動態生成查詢條件的需求,SODA將是必須的,這就是為什么在這介紹它。
簡單的查詢:
讓我們看看如何將我們熟悉的QBE查詢條件用SODA來表示,一個新的查詢對象通過query()方法從ObjectContainer中得到,
我們可以給它添加約束條件。查詢所有Pilot實例,我們通過Pilot來添加約束。
QueryExample.java: retrieveAllPilots
public static void retrieveAllPilots() {
????? ObjectContainer db=Db4o.openFile(YAPFILENAME);
???? try {
????????? Query query=db.query();
????? query.constrain(Pilot.class);?????????
? ObjectSet result=query.execute();
???????? listResult(result);
????? } finally {
??????? db.close();
???? }
?? }
基本上,我們交換我們真實的原形來用元數據來表述我們想要查找的對象:一個查詢圖是由查詢節點和約束組成。查詢節點
對于候選對象而言是一個占位符,而約束條件決定是否要添加或者去除候選對象。
我們簡單的查詢圖如下:
圖一
我們僅僅查詢任意候選對象(在這里,也就是數據庫中所有對象)它們的類型是Pilot將并加入結果集中。
通過pilot的名字來查詢,我們不得不進一步通過名字屬性和字符串的值來限制候選對象。
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);
??? }
在這里,decend意思是什么呢?其實正如我們真實原形,我們添加約束條件來約束我們候選中的子成員.
圖二
所以,一個候選者是pilot類型,有一個"name"屬性,并且值等于所給的字符串.
注意:對于類型的約束不是必須的,如果你去除,查詢結果將是所有具有"name"屬性.并且值等于所給的所有對象,但是這種查詢不符合一般的查詢行為.通過精確條件查找一個pilot是類似的,我們通過java原始對象區別.
QueryExample.java: retrievePilotByExactPoints
public static void retrievePilotByExactPoints(
??????????? ObjectContainer db) {
?????? Query query=db.query();
?????? query.constrain(Pilot.class);???????
?query.descend("points").constrain(new Integer(100));
??????? listResult(result);
??? }
有一個場景,我們不想通過緊缺屬性值來查詢而是同過指定范圍來查詢.這個功能由Constraint API 提供.首先,讓我們查詢名字不是"Michael Schumacher"的所有Pilots
QueryExample.java: retrieveByNegation
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);
??? }
這兒是個取反的布爾運算,其他的布爾運算也很接近.
QueryExample.java: retrieveByConjunction
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(new Integer(99)).and(constr);
??????? ObjectSet result=query.execute();
??????? listResult(result);
QueryExample.java: retrieveByDisjunction
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(new Integer(99)).or(constr);
??????? ObjectSet result=query.execute();
??????? listResult(result);
??? }
??? }
我們可以比較給定的值來約束.
QueryExample.java: retrieveByComparison
public static void retrieveByComparison(ObjectContainer db) ...{
?????? Query query=db.query();
??????? query.constrain(Pilot.class);
??????? query.descend("points")
??????????????? .constrain(new Integer(99)).greater();
??????? ObjectSet result=query.execute();
??????? listResult(result);
?? }
這個查詢接口允許默認值的查詢.
QueryExample.java: retrieveByDefaultFieldValue
public static void retrieveByDefaultFieldValue(
??????????????????? ObjectContainer db) ...{
??????? Pilot somebody=new Pilot("Somebody else",0);
??????? db.set(somebody);
??????? Query query=db.query();
??????? query.constrain(Pilot.class);
??????? query.descend("points").constrain(new Integer(0));
??????? ObjectSet result=query.execute();
??????? listResult(result);
??????? db.delete(somebody);
??? }
也可以對結果排序
QueryExample.java: retrieveSorted
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);
??? }
這些組合都是隨意的,請你試試.也許有許多查詢情景可能采用constrains的查詢接口無法實現,不過不用擔心,你可以
更隨意的應用Evaluations來實現.Evaluations 的討論在 Evaluations chapter.