我正在浏览official db4o tutorial的部分内容,并且我正在尝试修改它们为运行本机查询而提供的代码:
//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;
}
});
我已将此添加到他们的Pilot课程中:
//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个对象的数据库,并且db中的所有数据看起来都与OME eclipse插件一致。我测试了getGames(),它按预期工作。
我的问题是,当我运行修改后的查询时,它会返回数据库中的所有对象,我不明白为什么。我已经尝试更改查询以包含更标准的if,否则为false结构并更改查询以包括要求一定数量的点无效。无论我做什么,它似乎总是评估(pilot.getGames()&gt; = 100)为真。
任何人都可以帮助我理解原因吗?
答案 0 :(得分: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>
。 (以及其他未来的List-fields)。像这样:
class Pilot {
private List<String> games;
// rest
}
一旦访问size()或其他方法,这将“取消优化”本机查询,从而避免此错误。
现在,'deoptimized'查询运行速度非常慢。因此,如果您有很多对象且性能不可接受,我会为此查询执行此操作:创建一个存储列表当前大小的附加字段。然后,您将此附加大小字段用于此类查询。此外,您可以索引size-field。
我已报告this as a bug: