1

我正在使用 db4o 8.0。

我有一堂课

PostedMessage{
    @Indexed
    long receivedTime;
    @Indexed
    long sentTime;
    ...    
    //getter methods and setter methods for all the fields.
}

我将 PostedMessage 对象持久保存到 db4o 数据库。我已经将 15000 多个对象保存到 db4o 数据库。现在,当我运行以下查询时,它会导致 OutOfMemoryError。

    //Query to get PostedMessages between "start" and "end" dates.
    Query q = db.query();
    q.constrain(PostedMessage.class);
    Constraint from = q.descend("receivedTime").constrain(new Long(start.getTimeInMillis())).greater().equal();
    q.descend("receivedTime").constrain(new Long(end.getTimeInMillis())).smaller().equal().and(from);
    q.execute();//results in OutOfMemoryError

为了避免 OutOfMemoryError,我需要为 PostedMessage 类的字段添加索引。读这个

我有一个服务器/客户端配置。在打开 ObjectContainer 之前,我无法控制它的预配置。

在 ObjectContainer 刚刚打开并提供给我之后,我将不得不应用/附加索引 CommonConfiguration。

我知道如何创建配置。

    EmbeddedConfiguration appendConfig = Db4oEmbedded.newConfiguration();
    appendConfig.common().objectClass(EmailMessage.class).objectField("receivedTime").indexed(true);
    appendConfig.common().objectClass(EmailMessage.class).objectField("sentTime").indexed(true);

我无法弄清楚如何将此配置应用于已打开的 ObjectContainer。如何将索引添加到刚刚打开的 ObjectContainer?

EmbeddedConfigurationItem 的 apply()方法是答案吗?如果是,我可以获得一个示例代码来说明如何使用它吗?

已编辑:稍后在问题中添加了 @Indexed 注释。

4

4 回答 4

1

查看@Indexed参考文档

于 2012-08-27T13:43:22.280 回答
0

cl-r 使用 TA/TP 的建议对我来说就像一个魅力。见他上面的评论。

您还必须安装透明激活/透明持久性以避免在内存中加载不必要的对象。看教程中的第10&11章(在下载的db4o[Version].zip的doc/tutorial目录下] - cl-r

于 2012-08-30T20:31:45.497 回答
0

在我的特殊情况下,我需要遍历查询返回的 ObjectSet。

发现使用 IMMEDIATE 和 SNAPSHOT 查询方式也解决了 OutOfMemoryError 问题。时机也同样好。LAZY 模式不是我的解决方案。

从 100000 条已保存的 PostedMessage 中检索任何 100 条 PostedMessage 大约需要 8000 到 9000 毫秒。例如 1 到 100、1001 到 1100、99899 到 99999。

于 2012-09-04T06:41:08.903 回答
0

您应该为查询添加索引。否则 db4o 必须扫描所有对象。

您可以使用注释来做到这一点,如下所示:

import com.db4o.config.annotations.Indexed;

PostedMessage{
    @Indexed
    long receivedTime;
    long sentTime;

或者像你一样,使用配置:

EmbeddedConfiguration config = Db4oEmbedded.newConfiguration();
config.common().objectClass(EmailMessage.class).objectField("receivedTime").indexed(true);
config.common().objectClass(EmailMessage.class).objectField("sentTime").indexed(true);
ObjectContainer container = Db4oEmbedded.openFile(config,"your-data.db4o");

当容器已在运行时,您无法添加此配置。只有打开的时候。当索引尚不存在时,将在打开数据库时添加它们。打开时,您需要控制它。或者使用上面的注释。

于 2012-09-13T10:57:06.640 回答