2012-08-16 11 views
7

Szukam sposobu na wykonanie zapytania wymagającego JOIN. Czy jest jakiś sposób, aby to zrobić w przygotowanym oświadczeniu, lub jest jedyną dostępną opcją. Jeśli jedyną opcją jest rawQuery, to istnieje sposób automatycznego odwzorowania zwróconych obiektów na obiekty implementowanego Dao.ORMLite JOINs lub automatyczne mapowanie rawQuery

Przeszukałem dokumenty i przykłady, ale nie mogę znaleźć niczego, co pozwoli mi zmapować surowy wynik bazy danych do klasy obiektu ORM.

+1

FYI Daniel. Właśnie wydano ORMLite 4.22, który obsługuje proste zapytania JOIN. – Gray

+0

Poprzednio miałem ORMLite 4.23, który nie obsługiwał zapytań JOIN. Przeglądając daty wydania i sygnaturę czasową twojego komentarza, uważam, że chciałeś powiedzieć, że ORMLite 4.26, wydana 9/26/12, była pierwszą wersją obsługującą proste zapytania JOIN. Właśnie zaktualizowałem do wersji 4.45, która zdecydowanie ma JOIN. –

Odpowiedz

15

ORMLite obsługuje simple JOIN queries. Możesz również użyć raw-queries, aby to osiągnąć.

Możesz użyć Dao.getRawRowMapper(), aby zmapować znalezione zapytania lub utworzyć niestandardowego odwzorowania. Dokumentacja ma następujący przykładowy kod, który pokazuje w jaki sposób mapować String[] do swojego przedmiotu:

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

Dzięki @Gray. Znalazłem wszystkie niestandardowe elementy mapowania wierszy, ale chciałem, aby automatycznie zamienił się na obiekt, który już zdefiniowałem. Opcja JOIN QueryBuilder będzie następna na mojej liście życzeń! Jakiekolwiek słowo dotyczące tego, kiedy/jeśli to przyjdzie? – DanO

+0

Chcesz rozpocząć wątek na ormlite-dev? Jestem gotowy, aby to napisać. To, co będzie trudniejsze, to użyć sprzężenia do uwodnienia sub-obiektów. Ale zacznij wątek, a ja odpowiem: https://groups.google.com/forum/?fromgroups#!forum/ormlite-dev – Gray

+1

Utworzono wątek. – DanO

8

Znalazłem sposób automatycznego odwzorowania zestawu wyników na obiekt modelu.

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

Najważniejsze jest, aby wyciągnąć mapowania wierszy z obiektu Dao wykorzystaniem getRawRowMapper(), która będzie obsługiwać mapowanie dla Ciebie. Mam nadzieję, że pomoże to każdemu, kto ją znajdzie.

Nadal chciałbym mieć możliwość robienia złączeń w ramach QueryBuilder, ale dopóki to nie zostanie obsłużone, jest to według mnie najlepsza rzecz.

0

Raw zapytania automatycznego mapowania

miałem problem polach odwzorowanie zwyczaju SELECT które zwracają kolumny, które nie są obecny w dowolnym modelu tabeli. Stworzyłem więc niestandardowy RawRowMapper, który może mapować pola z niestandardowego zapytania na model niestandardowy. Jest to przydatne, gdy masz zapytanie zawierające pola, które nie odpowiadają żadnemu modelowi mapowania tabeli.

To RowMapper który wykonuje auto zapytania mapowania:

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

A oto Wykorzystanie:

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

ten powróci List<Model> z odwzorowanych wierszy wynikowych z Modelem jeśli kolumna kwerendy Nazwy i @DatabaseField(columnName są takie same

Powiązane problemy