我需要在不知道名字的情况下获得Field
(或字段列表)。
I.e:对于自定义实体管理员,我希望能够像这样进行方法调用:
cem.getEntities(MyEntity.class, ParamMap)
其中ParamMap应为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);
这至少可以将字符串的使用减少到一个位置,可以在不影响任何其他文件的情况下维护和更改字符串。但我仍然在寻找没有常数的解决方案,因此不需要与可用字段同步: - )
答案 0 :(得分: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方法的实现,在该方法中,您必须在运行时发出字节码。但是,这是可能的,可以做到。