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);

我试图避免使用查询,因为它首先应该“通用”,但也独立于字符串。(它们容易出错)。因此,实体管理器使用反射来确定他需要使用的表名和列名。

但是,我仍然需要使用

MyEntity.class.getDeclaredField("someFieldName")

这将简单地将容易出错的字符串“移出”实体管理器......

我想要实现的是这样的:

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

因此,无论实际字段的名称是什么,都可以以保存方式引用它,并且重构也将重构所有字段访问调用。

我不确定这是否可能。我可以为所有实体使用(封装的)枚举,但我希望有一种更通用的方法来实现这一点。


编辑:

一个好的解决方案似乎是使用常量:

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);

这至少将字符串的使用减少到一个位置,可以在该位置对其进行维护和更改,而不会影响任何其他文件。但我仍在寻找没有常量的解决方案,因此不需要与可用字段同步:-)

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 将返回一个包含两个条目的地图。

当然,这里的困难在于 createPattern 方法的实现,您必须在运行时发出字节码。但是,这是可能的并且可以做到。

于 2013-01-21T13:29:25.647 回答