2012-08-16 36 views
7

我正在尋找一種方法來執行需要JOIN的查詢。有沒有辦法在準備好的聲明中做到這一點,或者是我擁有的唯一選項。如果rawQuery是唯一的選擇,那麼有沒有辦法將返回的對象自動映射到正在實現的Dao的對象。ORMLite JOINs或rawQuery自動映射

我已經通過文檔和例子挖,但無法找到任何東西,讓我到原始數據庫結果映射到ORM對象類。

+1

FYI丹尼爾。 ORMLite 4.22剛剛發佈,它支持簡單的JOIN查詢。 – Gray 2012-09-27 20:25:21

+0

我以前有ORMLite 4.23不支持JOIN查詢。回顧發佈日期和評論時間戳,我相信你的意思是說,12/9/26發佈的ORMLite 4.26是第一個支持簡單JOIN查詢的版本。我剛剛更新到4.45,肯定有JOIN。 – 2013-03-26 20:47:28

回答

15

ORMLite支持simple JOIN queries。您也可以使用raw-queries來完成此操作。

您可以使用Dao.getRawRowMapper()爲你找到了查詢地圖,也可以創建自定義映射。該文件具有下面的示例代碼顯示瞭如何將String[]映射到你的對象:

GenericRawResults<Foo> rawResults = 
    orderDao.queryRaw(
    "select account_id,sum(amount) from orders group by account_id", 
    new RawRowMapper<Foo>() { 
      public Foo mapRow(String[] columnNames, 
       String[] resultColumns) { 
       return new Foo(Long.parseLong(resultColumns[0]), 
        Integer.parseInt(resultColumns[1])); 
     } 
    }); 
+0

謝謝@格雷。我已經找到了所有的自定義行映射器的東西,但只是希望它自動映射到我已經定義的對象。一個QueryBuilder JOIN選項將在我的心願單中出現!任何關於何時/如果即將到來的字眼? – DanO 2012-08-20 19:24:40

+0

想要在ormlite-dev上啓動一個線程?我準備寫下它。更難的是使用連接來保溼子對象。但開始線程,我會回覆:https://groups.google.com/forum/?fromgroups#!forum/ormlite-dev – Gray 2012-08-20 19:27:04

+1

創建線程。 – DanO 2012-08-20 19:43:37

8

我已經找到一種方法來自動設置地圖的模型對象的結果。

// return the orders with the sum of their amounts per account 
GenericRawResults<Order> rawResults = 
    orderDao.queryRaw(query, orderDao.getRawRowMapper(), param1) 

// page through the results 
for (Order order : rawResults) { 
    System.out.println("Account-id " + order.accountId + " has " 
    + order.totalOrders + " total orders"); 
} 

rawResults.close(); 

,關鍵是要利用getRawRowMapper(),它將爲您處理映射你的對象Dao拉行映射。我希望這可以幫助任何發現它的人。

我還是喜歡做的能力加入QueryBuilder內,但直到被支持,這在我看來是未來最好的事情。

0

原始查詢自動映射

我從自定義字段映射的問題,選擇哪個返回不在列出現在任何表格模型中。所以我製作了自定義RawRowMapper,可以將字段從自定義查詢映射到自定義模型。當您的查詢具有與任何表格映射模型不對應的字段時,這非常有用。

這是的RowMapper執行查詢自動映射:

public class GenericRowMapper<T> implements RawRowMapper<T> { 

private Class<T> entityClass; 
private Set<Field> fields = new HashSet<>(); 
private Map<String, Field> colNameFieldMap = new HashMap<>(); 

public GenericRowMapper(Class<T> entityClass) { 
    this.dbType = dbType; 
    this.entityClass = entityClass; 
    Class cl = entityClass; 
    do { 
     for (Field field : cl.getDeclaredFields()) { 
      if (field.isAnnotationPresent(DatabaseField.class)) { 
       DatabaseField an = field.getAnnotation(DatabaseField.class); 
       fields.add(field); 
       colNameFieldMap.put(an.columnName(), field); 
      } 
     } 
     cl = cl.getSuperclass(); 
    } while (cl != Object.class); 
} 

@Override 
public T mapRow(String[] columnNames, String[] resultColumns) throws SQLException { 
    try { 
     T entity = entityClass.newInstance(); 
     for (int i = 0; i < columnNames.length; i++) { 
      Field f = colNameFieldMap.get(columnNames[i]); 
      boolean accessible = f.isAccessible(); 
      f.setAccessible(true); 
      f.set(entity, stringToJavaObject(f.getType(), resultColumns[i])); 
      f.setAccessible(accessible); 
     } 
     return entity; 
    } catch (InstantiationException e) { 
     throw new RuntimeException(e); 
    } catch (IllegalAccessException e) { 
     throw new RuntimeException(e); 
    } 
} 

public Object stringToJavaObject(Class cl, String result) { 
    if (result == null){ 
     return null; 
    }else if (cl == Integer.class || int.class == cl) { 
     return Integer.parseInt(result); 
    } else if (cl == Float.class || float.class == cl) { 
     return Float.parseFloat(result); 
    } else if (cl == Double.class || double.class == cl) { 
     return Double.parseDouble(result); 
    } else if (cl == Boolean.class || cl == boolean.class) { 
     try{ 
      return Integer.valueOf(result) > 0; 
     }catch (NumberFormatException e){ 
      return Boolean.parseBoolean(result); 
     } 
    } else if (cl == Date.class) { 
     DateLongType lType = DateLongType.getSingleton(); 
     DateStringType sType = DateStringType.getSingleton(); 
     try { 
      return lType.resultStringToJava(null, result, -1); 
     } catch (NumberFormatException e) { 
      try { 
       return sType.resultStringToJava(null, result, -1); 
      } catch (SQLException e2) { 
       throw new RuntimeException(e); 
      } 
     } 
    } else { 
     return result; 
    } 
} 
} 

這裏是使用

class Model{ 
    @DatabaseField(columnName = "account_id") 
    String accId; 
    @DatabaseField(columnName = "amount") 
    int amount; 
} 

String sql = "select account_id,sum(amount) amount from orders group by account_id" 
return queryRaw(sql,new GenericRowMapper<>(Model.class)).getResults() 

這將返回List<Model>與映射的結果行如果查詢列到模型名稱和@DatabaseField(columnName是相同的