0

Field名前を知らなくても、(またはフィールドのリスト)を取得する必要があります。

つまり、カスタム エンティティ マネージャーの場合、次のようにメソッド呼び出しを実行できるようにしたいと考えています。

cem.getEntities(MyEntity.class, ParamMap)ParamMap は Type である必要がありMap<Field, Object>ます。

現時点でできることは、次のようなものです。

Map<Field, Object> params = new HashMap<Field, Object>();
params.put(MyEntity.class.getDeclaredField("someFieldName"), 20);
List<MyEntity> entitysWithSomeFieldNameEquals20 = cem.getEntities(MyEntity.class, params);

そもそも「一般的」に機能するだけでなく、文字列から独立しているため、クエリの使用を避けようとしています。(エラーが発生しやすい)。したがって、Entity Manager はリフレクションを使用して、使用する必要があるテーブルと列の名前を決定します。

しかし、私はまだ使用する必要があります

MyEntity.class.getDeclaredField("someFieldName")

これにより、エラーが発生しやすい文字列がエンティティマネージャーから「外に」簡単に移動されます...

私が達成しようとしているのは、次のようなものです。

MyEntity.class.getDeclaredField(MyEntity.class.fields.someFieldName.toString())

そのため、実際のフィールドの名前に関係なく、保存方法で参照でき、リファクタリングによってすべてのフィールド アクセス呼び出しもリファクタリングされます。

これが可能かどうかはわかりません。すべてのエンティティに対して (カプセル化された) 列挙型を使用することもできますが、これを実現するためのより一般的な方法があることを願っています。


編集:

良い解決策の 1 つは、定数を使用することです。

public class MyEntity{
    private static string SOME_FIELD = "some_field_name_in_database";

    @Column(name = SOME_FIELD);
    private String someField;

}

...
Map<String, Object> params = new HashMap<String, Object>();
params.put(MyEntity.SOME_FIELD, matchValue);
List<MyEntity> result = eem.getEntities(MyEntity.class, params);

これにより、少なくとも文字列の使用が正確に 1 つの場所に削減され、他のファイルに影響を与えることなく維持および変更できます。しかし、私はまだ定数のない解決策を探しているので、定数を利用可能なフィールドと同期させる必要はありません:-)

4

1 に答える 1

0

わかりました、これは単なるアイデアであり、実装するのは簡単ではありませんが、うまくいく可能性があります.

MyEntity が次のようになっているとします。

public class MyEntity {
  private String foo;
  private String bar;

  public String getFoo() { return this.foo; }
  public void setFoo(String foo) { this.foo = foo; }

  public String getBar() { return this.bar; }
  public void setBar(String bar) { this.bar = bar; }

}

そしてインターフェースがあります:

public interface Pattern {
  public Class<?> getEntityClass();
  public Map<Field, Object> getFields();
}

クラスを受け取り、指定されたクラスのインスタンスであるパターン オブジェクトを生成するメソッドがあります。

public class PatternFactory {
  public <T> T createPattern(Class<T> klass) {
    // magic happens here
  }
}

発行されたインスタンスの要件はPattern、メソッド getFields が明示的に設定されたフィールドのみを返すように、インターフェイスを実装する必要があることです。GetEntityClass はエンティティ クラスを返す必要があります。次に、カスタム エンティティ マネージャーを次のように実装できます。

public class EntityManager {
  public <T> Collection<T> getEntities(T pattern) {
    if (!(pattern instanceof Pattern))
      throw new IllegalArgumentException();

    Class<?> klass = ((Pattern) pattern).getEntityClass();
    Map<Field, Object> fields = ((Pattern) pattern).getFields();
    // fetch objects here
  }
}

次に、次のように使用できます。

PatternFactory pf = // obtain somehow
EntityManager em = // obtain somehow
MyEntity pattern = pf.createPattern(MyEntity.class);
pattern.setFoo("XYZ");
pattern.setBar(null);
Collection<MyEntity> result = em.getEntities(pattern);

この場合、pattern.getFields は 2 つのエントリを持つマップを返します。

もちろん、ここでの問題は、実行時にバイトコードを発行する必要がある createPattern メソッドの実装にあります。ただし、これは可能であり、実行できます。

于 2013-01-21T13:29:25.647 に答える