2012-08-16 5 views
7

Ich bin auf der Suche nach einer Möglichkeit, eine Abfrage, die ein JOIN erfordert. Gibt es eine Möglichkeit, dies in einer vorbereiteten Aussage zu tun, oder ist die rawQuery die einzige Option, die ich habe. Wenn rawQuery die einzige Option ist, gibt es eine Möglichkeit, die zurückgegebenen Objekte automatisch den Objekten des implementierten Dao zuzuordnen.ORMLite JOINs oder rawQuery Auto Mapping

Ich habe die Dokumente und Beispiele durchforstet, kann aber nichts finden, was mir erlaubt, das Rohdatenergebnis einer ORM-Objektklasse zuzuordnen.

+1

FYI Daniel. ORMLite 4.22 wurde gerade veröffentlicht und unterstützt einfache JOIN-Abfragen. – Gray

+0

Ich hatte zuvor ORMLite 4.23, die JOIN-Abfragen nicht unterstützt. Ich glaube, Sie wollten die Veröffentlichungsdaten und den Zeitstempel Ihres Kommentars Revue passieren lassen. ORMLite 4.26, veröffentlicht am 26.09.12, war die erste Version, die einfache JOIN-Abfragen unterstützte. Ich habe gerade auf 4.45 aktualisiert, was definitiv JOIN ist. –

Antwort

15

ORMLite unterstützt simple JOIN queries. Sie können dazu auch raw-queries verwenden.

Sie können die Dao.getRawRowMapper() verwenden, um die Abfragen so abzubilden, wie Sie sie gefunden haben, oder Sie können einen benutzerdefinierten Mapper erstellen. Die Dokumentation hat den folgenden Beispielcode, der zeigt, wie die String[] in Ihr Objekt zur Karte:

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

Danke @Gray. Ich hatte alle benutzerdefinierten Mapper-Dateien gefunden, wollte sie aber nur automatisch einem Objekt zuordnen, das ich bereits definiert hatte. Eine QueryBuilder-JOIN-Option wäre als nächstes auf meiner Wunschliste! Irgendein Wort bezüglich wann/wenn das kommt? – DanO

+0

Möchten Sie einen Thread auf Ormlite-dev starten? Ich bin bereit, es zu schreiben. Was schwieriger wird, ist die Verwendung von Join, um Unterobjekte zu hydratisieren. Aber starte den Thread und ich antworte: https://groups.google.com/forum/?fromgroups#!forum/ormlite-dev – Gray

+1

Erstellt den Thread. – DanO

8

Ich habe eine Möglichkeit gefunden, eine Ergebnismenge automatisch einem Modellobjekt zuzuordnen.

// 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(); 

Der Schlüssel ist, um die Zeile Mapper von Ihrem Objekt zu ziehen DaogetRawRowMapper() verwenden, die die Zuordnung für Sie handhaben. Ich hoffe, das hilft jedem, der es findet.

Ich würde immer noch gerne die Möglichkeit, Joins innerhalb der QueryBuilder tun, aber bis das unterstützt wird, ist dies das nächstbeste meiner Meinung nach.

0

Raw Abfrage Auto-Mapping

Ich hatte Problem der Mapping-Felder von benutzerdefinierten auswählen, welche Spalten zurückgeben, die nicht in jedem Tabellenmodell vorhanden. So machte ich benutzerdefinierte RawRowMapper, die Felder von benutzerdefinierten Abfrage zu benutzerdefinierten Modell zuordnen können. Dies ist nützlich, wenn Sie eine Abfrage mit Feldern haben, die keinem Tabellenmapping-Modell entsprechen.

Dies ist RowMapper die Abfrage Auto-Mapping ausführt:

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; 
    } 
} 
} 

Und hier ist die Nutzung:

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() 

Dies wird zurückkehren List<Model> mit kartiert Ergebniszeilen, wenn Abfragespalte zu Modell Namen und @DatabaseField(columnName sind die gleichen

Verwandte Themen