0

我正在浏览官方 db4o 教程的部分内容,并且正在尝试修改它们为您提供的用于运行本机查询的代码:

//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 个对象的数据库,并且使用 OME eclipse 插件,数据库中的所有数据看起来都是正确的。我已经测试了 getGames() 并且它按预期工作。

我的问题是,当我运行修改后的查询时,它返回数据库中的所有对象,我不明白为什么。我尝试更改查询以包含更标准的如果为真,否则为假结构,并更改查询以包括需要一定数量的点无济于事。无论我做什么,它似乎总是评估 (pilot.getGames() >= 100) 为真。

谁能帮我理解为什么?

4

1 回答 1

0

我想你发现了一个错误。db4o 尝试将native-queries 转换为 soda-query。这避免了实例化对象来执行查询。现在,这个翻译不知何故不起作用!

当您关闭优化时,它会起作用。您可以通过配置执行此操作:

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

但是我不推荐这样做,因为这样所有查询都会运行缓慢。我找到了一个简单的解决方法。games将-field的声明更改为List<String>. (以及其他未来的列表字段)。像这样:

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

一旦您访问 size() 或其他方法,这将“取消优化”本机查询,从而避免此错误。

现在,“去优化”的查询可能会运行得很慢。因此,如果您有很多对象并且性能无法接受,我会为此查询执行此操作:创建一个附加字段来存储列表的当前大小。然后,您将这个额外的大小字段用于此类查询。此外,您还可以索引大小字段。

我已将此报告为错误

于 2010-03-03T21:23:38.753 回答