2

OneToMany 関係にある Parent と Child の 2 つのモデル (議論のために簡略化) があります。Child には String プロパティ タイプがあります。メソッドを作成したい

public List<String> Parent.getTypes()

タイプの個別のリストを返します。これは私が思いつくことができる最高のものです:

public List<String> getTypes() {
    String sql = "select distinct type from child where parent_id=:id";

    SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
    sqlQuery.setParameter("parent", id);

    List<SqlRow> rows = sqlQuery.findList();
    List<String> types = new ArrayList<String>(rows.size());
    for (SqlRow row : rows)
        directions.add(row.getString("type"));

    return types;
}

このメソッドは頻繁に呼び出されると思います。これはあまり効率的ではないと思います。1つは、パラメーターを除いてクエリが同じであっても、 getTypes() が呼び出されるたびに新しい SqlQuery を作成しています。

再利用可能な SqlQuery を初期化するのに最適な場所はどこですか? 親モデルの最上位で実行しようとしましたが、モデルの初期化時に DB の準備ができていないと推測されるため、例外が発生します。そこで null にして、最初に getTypes() が呼び出されたときに初期化できると思います。これを行う「正しい」方法は何ですか?

4

1 に答える 1

3

キャッシュは非常に安価で便利です。つまり、10 分間キャッシュできます。

public List<String> getTypes(Integer parentId) {

    List<String> types = (List<String>) Cache.get("listOfTypes");
    if (types == null) {
        List<SqlRow> rows = Ebean
             .createSqlQuery("select distinct type from child where parent_id=:id")
             .setParameter("id", parentId)
             .findList();

        types = new ArrayList<String>(rows.size());
        for (SqlRow row : rows)
            types.add(row.getString("type"));

        Cache.set("listOfTypes", types, 600);
    }

    return types;
}
于 2012-10-26T10:07:31.023 に答える