我的目標在這裏做一個非常簡單的對象< - >實體映射這裏是我迄今所做的,這是遞歸的:翻譯對象爲數據存儲區實體
/**
*
* 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());
}
問題是否存在任何現有的Object-to-Entity映射代碼?我不是真的在尋找完整的ORM框架,只是一個簡單的POJO
到Entity
轉換器代碼。這個代碼是否以任何方式膨脹?
你的意思是除了在https://developers.google.com/appengine/docs/java/storage#app_engine_datastore上提到的那些嗎? – alex
我有類似的東西,但沒有使用反射(反射速度比它應該在App Engine上慢)。我使用代碼生成。 –