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

私の場合、TA/TP を使用するという cl-r の提案は魅力的でした。上記の彼のコメントを参照してください。

不要なオブジェクトをメモリにロードしないように、Transparent Activation/Transparent Persistence もインストールする必要があります。チュートリアルの第 10 章と第 11 章を見てください (ダウンロードした db4o[Version].zip の doc/tutorial ディレクトリにあります] - cl-r

于 2012-08-30T20:31:45.497 に答える
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 に答える
0

私の特定のケースでは、クエリによって返された ObjectSet を反復処理する必要があります。

IMMEDIATE および SNAPSHOT クエリ モードを使用すると、OutOfMemoryError 問題も解決されることがわかりました。また、タイミングも同様に良好でした。LAZY モードは私にとって解決策ではありません。

保存された 100000 個の PostedMessages から 100 個の PostedMessages を取得するのに約 8000 ~ 9000 ミリ秒かかりました。例: 1 ~ 100、1001 ~ 1100、99899 ~ 99999。

于 2012-09-04T06:41:08.903 に答える