2014-04-23 27 views
-1

我的目標在這裏做一個非常簡單的對象< - >實體映射這裏是我迄今所做的,這是遞歸的:翻譯對象爲數據存儲區實體

/** 
    * 
    * 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框架,只是一個簡單的POJOEntity轉換器代碼。這個代碼是否以任何方式膨脹?

+0

你的意思是除了在https://developers.google.com/appengine/docs/java/storage#app_engine_datastore上提到的那些嗎? – alex

+0

我有類似的東西,但沒有使用反射(反射速度比它應該在App Engine上慢)。我使用代碼生成。 –

回答

-1

您正在編寫另一個持久性庫的痛苦方式。要小心,「純」對象模型幾乎不能與數據存儲實體匹配。在某個時候,你會做出妥協來匹配底層的實體結構,那時你會意識到一個更好的圖書館一直在做這件事。

例如:你提供你的實體的父密鑰,但如果是實體鍵,如果你只是想更新呢?如果在某個時候你不想爲一個小查詢加載所有的對象圖,你將如何處理延遲加載?你如何序列化密鑰?那麼Blob s和byte[]?你如何處理傳統的屬性?

請你幫個忙,你花的是已經存在,你是太大了,一個人的問題絆倒之前使用經過驗證的持久性工具的東西工作的前兩週。如果您需要保持純粹的對象模型(例如,如果您在前端使用GWT),那麼將持久類映射到您的POJO。

如果你真的不需要像,說,物化,這可能意味着你將與低級別的API的靈活性更好。將實體映射到您的類並不需要很長時間。

的底線是,通過編寫自己的「框架」,你就錯過了的手冊 - &的靈活性-boring底層API 剛性,但固工具,做這一切都比你更好。

相關問題