5

私は自分のAndroidプロジェクトでormliteを使用しています。私は2つのクラスがあります

@DatabaseTable(tableName = "usershows")
public class UserShow {
    @DatabaseField(id = true)
    private Integer showId;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<Episode> episodes;
    ...
}

@DatabaseTable(tableName = "episodes")
public class Episode {
    @DatabaseField(id = true)
    private Integer episodeId;

    @DatabaseField(foreign = true)
    private UserShow show;
    ...
}

のようにUserShowsオブジェクトを保存しています

UserShow show = new UserShow();
userShowDao.create(show);

for (Episode e: eps) {
    e.setShow(show);
    episodeDao.create(e); 
} 

UserShowオブジェクトには、外部のレイジーコレクションエピソードがありますが、すべてのuserShowを取得しようとすると:

shows = userShowsDao().queryForAll();

エピソードのコレクションを含むすべてのショーオブジェクトを取得しています。なぜこれが起こるのですか?コレクションは怠惰で、nullか何か他のものを取得する必要がありますが、Episodeオブジェクトのコレクションはありません。このコレクションを本当に怠惰にする方法は?ORMLiteに、遅延コレクションなしでオブジェクトを取得し、本当に必要なときに初期化する機能があると便利です。たとえば、Hibernate.initializeメソッドとして。

ありがとう!

4

2 に答える 2

4

レイジーコレクションは十分にテストされており、他の多くの人によって使用されているため、バグがある可能性はありますが、レイジーコレクションクラスにだまされている可能性が高くなります。

UserShowオブジェクトがDAOから取得されると、はepisodesnullではなく、代わりに。のインスタンスで設定されますLazyForeignCollectionEpisodeただし、追加のクエリは行われず、コレクションに含まれるデータはありません。userShow.getEpisodes().iterator()次に、などのコレクションのメソッドの1つを呼び出すと、その時点でのクエリが実行され、その番組のエピソードを繰り返すことができます。それが怠惰なコレクションの仕組みです。

それでも怠惰なコレクションが機能していないと思われる場合は、番組にエピソードデータがあると判断する方法を教えてください。どのクエリがどこで実行されているかを確認するには、ORMLiteを使用してAndroidロギングを有効にします。


編集:

@Georgyがデバッガーを使用してコレクションを調査していたことがわかりました。デバッガーは、同じメソッドiterator()またはtoArray()メソッドを呼び出している可能性が高く、その瞬間にコレクションクエリが発行されます。そのため、デバッガーが要求する前に、コレクションにエピソードはありませんでした。

于 2011-08-30T13:41:02.570 に答える
1

あなたの例は大丈夫です。関連するテストテーブルを作成し、2usershowsと3を挿入しましたepisodes。次に、MySQLログを調整しました(MySQLを実行して設定します-http://dev.mysql.com/doc/refman/5.5/en/query-log.html--general-log=<log file name>を参照)。

完全なテストGroovyスクリプト:

import com.j256.ormlite.dao.DaoManager
import com.j256.ormlite.jdbc.JdbcConnectionSource
cs = new JdbcConnectionSource('jdbc:mysql://localhost/episode?user=root')
epDao = DaoManager.createDao(cs,Episode)
usDao = DaoManager.createDao(cs,UserShow)
usDao.queryForAll().each { println it }

ログには、実行されたselectステートメントが1つだけ表示されます。

110830 13:11:09     1 Query SELECT * FROM `usershows`

最後の行を次のように変更します(これはすべてのユーザーショーを繰り返し、それぞれのエピソードフィールドを取得します:

usDao.queryForAll().each { println it.episodes }

結果:

110830 13:15:31     1 Query SELECT * FROM `usershows`
                    1 Query SELECT * FROM `episodes` WHERE `show_id` = 1
                    1 Query SELECT * FROM `episodes` WHERE `show_id` = 2
于 2011-08-30T12:20:19.753 に答える