3

現在取り組んでいるプロジェクトでは、プロパティをドメイン クラスに動的に追加し、後でデータベースに永続化する必要があります。一般に、「通常の」ドメイン クラスにアタッチされたキー/バリュー ストアが必要です。残念ながら、NoSQL データベース (Redis など) は使用できません。

私のアプローチは、追加のプロパティを別のテーブルsave()内で識別するafterInsertafterUpdate、別のテーブルに書き込むことで処理することです.ドメインクラス内でマッププロパティを使用するのではなく、追加の「フィールド」テーブルを使用することをお勧めします(検索をより適切にサポートするため)。

metaClass アプローチを使用してプロパティを追加しようとしました:

person.metaClass.middlename = "Biterius"
assert person.middlename == "Biterius"    // OK

これは機能し、afterInsert/afterUpdate メソッドで追加のプロパティを特定できますが、その後値を変更できないようです。つまり、次のようには機能しません。

person.middlename = "Tiberius"
assert person.middlename == "Tiberius"    // FAIL

次に、Person クラスを Expando クラスで直接 ("Person extends Expando") および抽象中間クラスを介して ("Person extends AbstractPerson" および "AbstractPerson extends Expando") 拡張することにより、 Expando アプローチを試みました。

def person = new Person()
assert person in Person          // OK
assert person in AbstractPerson  // OK
assert person in Expando         // OK

どちらのバリアントも機能しませんでした。任意の「プロパティ」に値を割り当てることはできましたが、値が保存されませんでした。

person.mynewproperty = "Tiberius"  // no MissingPropertyException is thrown 
println person.mynewproperty       // returns null

では、実行時にプログラムでドメイン クラスにプロパティを追加し、変更して afterInsert または afterUpdate 中に取得し、「フィールド」テーブルに「手動で」保存するにはどうすればよいでしょうか。

または、私は何か完全に間違っていますか?これを行う他の/より簡単な方法はありますか?

4

2 に答える 2

0

ドメイン オブジェクトで文字列のマップを作成し、余分なデータをそこに手動で保存してみませんか? 複雑なデータを格納していない限り、必要なものを文字列との間でキャストできるはずです。

于 2012-09-21T18:48:41.260 に答える
0

DB を「NoSQL」のものに変えてみませんか?

私のプロジェクトの 1 つで、文字列プロパティを使用してマップを JSON オブジェクトとして保存しました。Groovy の場合、マップと JSON オブジェクト間の変換は大きな問題ではありません。また、プロパティを持つオブジェクトと同じようにマップにアクセスできるため、このソリューションは非常に便利であることがわかりました。

唯一の欠点: String プロパティのサイズを事前に計画する必要があります...

更新:申し訳ありませんが、検索をサポートしたいことを読んでください...

どうですか

class Person {
  ...
  static hasMany = [extProperties:KeyValue]
  ...
  def invokeMethod(String name, args) {
    if (name.startsWith('get')) {
       //an unknown properties's getter is called
    }
    //add same for setter
  }
}


class KeyValue {
  String key
  String value
}

そのようなスキーマがあれば、必要なすべての自由が得られると思います。がなくてもhasMany、 を利用invokeMethodして外部テーブルを処理できます...

ゲッターとセッターは、値を一時的な文字列プロパティ ( static transients = ['myTransientProperty']) に保存できます。afterInsertこのプロパティは/ `afterUpdate' イベントで利用できるはずです。

于 2012-09-21T18:15:54.987 に答える