【发布时间】:2014-04-23 17:50:06
【问题描述】:
我的目标是做一个非常简单的对象这里的实体映射是我到目前为止所做的,这是递归的:
/**
*
* Create Entity objects that can be persisted into the GAE datastore,
* including its Parent-Child relationships (if necessary).
*
* @param parent parent of the generated Entity or Entities
* @param instance
* @return
*/
public Entity createEntityFrom(Key parent, Object instance){
Preconditions.checkNotNull(instance, "Object should not be null");
if (stack == null){ // List<Entity> stack;
stack = new LinkedList<Entity>();
}
stack.clear();
Key key = createKeyFrom(parent, instance); // inspect kind and create key
Map<String,Object> props = new LinkedHashMap<String, Object>();
List<Entity> target = null;
Entity e = new Entity(key);
Field[] fields = instance.getClass().getDeclaredFields();
for (Field field : fields) {
if (target == null){
target = new LinkedList<Entity>();
}
String fieldName = field.getName();
if(field.isAnnotationPresent(Id.class)){
// skip
continue;
}
try {
boolean isAccessible = field.isAccessible();
field.setAccessible(true);
Class<?> clazz = field.getType();
Object fieldValue = field.get(instance);
if (fieldValue == null){
e.setProperty(fieldName, null);
} else if (fieldValue instanceof String) {
setProperty(e, fieldName, fieldValue);
} else if(fieldValue instanceof Number
|| fieldValue instanceof Long
|| fieldValue instanceof Integer
|| fieldValue instanceof Short) {
setProperty(e, fieldName, fieldValue);
} else if(fieldValue instanceof Boolean) {
setProperty(e, fieldName, fieldValue);
} else if(fieldValue instanceof Date) {
setProperty(e, fieldName, fieldValue);
} else if(fieldValue instanceof User) { // GAE support this type
setProperty(e, fieldName, fieldValue);
} else if(fieldValue instanceof List) {
LOG.debug( "Processing List valueType");
if (field.isAnnotationPresent(Embedded.class)){
setProperty(e, fieldName, createEmbeddedEntityFromList(parent, (List) fieldValue));
} else {
// TODO
List<Object> list = (List<Object>) fieldValue;
List<Entity> result = new LinkedList<Entity>();
for (Object o : list){
//result = createEntityFrom(e.getKey(), o);
}
}
} else if(fieldValue instanceof Map){
LOG.debug( "Processing Map valueType");
if (field.isAnnotationPresent(Embedded.class)){
setProperty(e, fieldName, createEmbeddedEntityFromMap(parent, (Map) fieldValue));
} else {
Entity mapEntity = new Entity(KeyStructure.createKey(e.getKey(), "kind", "key"));
Map map = (Map) fieldValue;
Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry = (Map.Entry) it.next();
Object entryKey = entry.getKey();
Object entryVal = entry.getValue();
validateKey(entryKey);
if(entryKey instanceof String){
//createEntityFrom()
} else if (entryKey instanceof Long){
} else {
}
}
}
} else {
// For primitives
if (clazz.equals(int.class)){
int i = (Integer) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(boolean.class)){
boolean i = (Boolean) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(byte.class)){
byte i = (Byte) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(short.class)){
short i = (Short) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(long.class)){
long i = (Long) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(float.class)){
float i = (Float) fieldValue;
setProperty(e, fieldName, i);
} else if (clazz.equals(double.class)){
double i = (Double) fieldValue;
setProperty(e, fieldName, i);
} else { // POJO
if (field.isAnnotationPresent(Parent.class)){
// update key
Key oldKey = e.getKey();
Entity parentEntity = createEntityFrom(null, field); // then add to the stack
// TODO
} else if (field.isAnnotationPresent(Child.class)){
Entity childEntity = createEntityFrom(e.getKey(), field);
setProperty(e, fieldName, childEntity.getKey());
}
Key parentKey = e.getKey();
Entity child = createEntityFrom(parentKey, fieldValue);
setProperty(e, fieldName, child.getKey());
stack.add(e);
}
}
field.setAccessible(isAccessible);
} catch(IllegalAccessException ex){
ex.printStackTrace();
}
}
return e;
}
测试
它的使用方法如下:
@Test
public void test(){
Friend f = new Friend(); // one Entity
f.setName("TestUser");
f.setAge(25);
f.setNewAddress(new Address("Test City")); // one Entity, @Child
f.setOldAddress(new Address("Old Test City")); // not included, @Embedded
List<Entity> stack = new LinkedList<Entity>();
ObjectMapper mapper = new ObjectMapper();
mapper.createEntityFrom(null, f);
assertEquals(2, stack.size());
}
问题是否有任何现有的对象到实体映射代码?我并不是真的在寻找完整的承诺 ORM 框架,只是一个简单的 POJO 到 Entity 转换器代码。这段代码是否臃肿?
【问题讨论】:
-
你的意思是除了developers.google.com/appengine/docs/java/…上提到的那些?
-
我有类似的东西,但没有使用反射(反射在 App Engine 上比它应该慢)。我是使用代码生成实现的。
标签: java google-app-engine google-cloud-datastore