2010-03-03 54 views
0

我一眼通過official db4o tutorial的部分,我想做出修改的代碼時,他們給你運行原生查詢:問題使用db4o(JAVA)運行查詢

//the original 
List<Pilot> pilots = db.query(new Predicate<Pilot>() { 
    public boolean match(Pilot pilot) { 
     return pilot.getPoints() == 100; 
    } 
}); 

//modified 
List<Pilot> pilots = db.query(new Predicate<Pilot>() { 
    public boolean match(Pilot pilot) { 
     return pilot.getGames() >= 100; 
    } 
}); 

我已經添加到了他們試點班:

//in declarations 
private ArrayList<String> games; 

//modified constructors 
public Pilot() { 
    this.name=null; 
    this.points=0; 
} 
public Pilot(String name,int points) { 
    this.name=name; 
    this.points=points; 
    this.games = new ArrayList<String>(); 
    int numGames = (int) (Math.random() * 1000 + 1); 
    for(int i=0;i<numGames;i++) { 
     this.games.add(name=" vs Computer"); 
    } 
} 

//new method 
public int getGames() { 
    return games.size(); 
} 

我已經填充了使用第二個構造500個對象的數據庫,並在數據庫中的所有數據正確與OME月食插件。我測試了getGames()並且它按預期工作。

我的問題是,當我運行修改後的查詢時,它返回數據庫中的所有對象,我不明白爲什麼。我試着改變查詢來包含一個更爲標準的如果是真的,否則錯誤的結構和改變查詢包括需要一定數量的點無濟於事。無論我做什麼,似乎總是評估(pilot.getGames()> = 100)爲真。

任何人都可以幫我理解爲什麼嗎?

回答

0

我想你已經發現了一個錯誤。 db4o試圖翻譯native-queries into a soda-query。這避免了實例化對象來執行查詢。現在在這裏這種翻譯不知何故不起作用!

當您關閉優化時,它可以正常工作。你可以通過配置來做到這一點:

EmbeddedConfiguration cfg = Db4oEmbedded.newConfiguration(); 
    cfg.common().optimizeNativeQueries(false); 
    ObjectContainer db = Db4oEmbedded.openFile(cfg,DB_FILE) 

但是,我不建議這樣做,因爲然後所有的查詢將運行緩慢。我找到了一個簡單的解決方法。將games字段的聲明更改爲List<String>。 (和其他未來的列表字段)。就像這樣:

class Pilot { 
     private List<String> games; 
     // rest 
    } 

這將「deoptimize」只要你訪問的大小()或其他方法本機查詢,從而避免了這種錯誤。

現在'優化'查詢可以運行得非常慢。所以,如果你有很多的對象,性能是不可接受的,我會爲此查詢做到這一點:創建一個存儲列表的當前大小的附加字段。然後你使用這個額外的大小字段進行這種查詢。此外,您可以索引大小字段。

我舉報了this as a bug

+0

非常感謝,先生! – fusion2004