2012-07-26 14 views
7

Korzystając z ORMLite na Androida, muszę zbudować zapytanie, które zwróci zamówienia według identyfikatora zamówienia lub nazwy klienta. Proszę wziąć pod uwagę następujące deklaracje klas:ORMLite - Zapytanie o obce pole

@DatabaseTable(tableName = "order") 
public class Order { 
    @DatabaseField(generatedId = true) 
    private Long id; 

    @DatabaseField(foreign = true, canBeNull = false, foreignAutoRefresh = true, columnName = "customer_id") 
    private Customer customer; 

    // default constructor, getters and setters... 
} 

@DatabaseTable(tableName = "customer") 
public class Customer { 
    @DatabaseField(generatedId = true) 
    private Long id; 

    @DatabaseField 
    private String name; 

    // default constructor, getters and setters... 
} 

Surowa SQL szukam byłoby coś takiego:

SELECT 
    o.* 
FROM 
    order o 
    JOIN customer c on 
     o.customer_id = c.id 
WHERE 
    (o.id = ?) OR (c.name = ?) 

Jaki jest najlepszy sposób to zrobić przy użyciu ORMLite?

+0

http://stackoverflow.com/questions/17618198/error-in-query-with-join-with-ormlite Proszę mi pomóc: (@Gray – fabiodresch

Odpowiedz

12

ORMLite obsługuje teraz simple join queries.

Więc zapytanie będzie wyglądać następująco:

QueryBuilder<Customer, Integer> customerQb = customerDao.queryBuilder(); 
SelectArg nameSelectArg = new SelectArg(); 
// this gives the c.name = ? 
customerQb.where().eq("name", nameSelectArg); 
QueryBuilder<Account, Integer> orderQb = orderDao.queryBuilder(); 
SelectArg idSelectArg = new SelectArg(); 
// this gives the o.id = ? 
orderQb.where().eq("id", idSelectArg); 
orderQb.join(customerQb); 
// then you set the args and run the query 
nameSelectArg.setValue("jim"); 
idSelectArg.setValue(1); 
List<Order> results = orderQb.join(customerQb).query(); 
+0

Grey, po prostu przyjrzeliśmy się OrmLite jako potencjalnej ORM-owi na Androida i zauważyliśmy, że relacje są ładowane przez osobne zapytania zamiast połączeń, przez co cierpią na problem N + 1. Jakie było uzasadnienie wdrożenia tego w ten sposób? Obecnie oznacza to, że 'queryForAll' na 100' 'A'''''''''''''''', gdzie każdy ma' B' wyda 101 zapytań zamiast jednego. 1 zapytanie, aby pobrać wszystkie 'A's, następnie kolejne 100 zapytań, aby pobrać' B' dla każdego 'A'. – Matthias

+0

Krótka odpowiedź brzmi, ponieważ nie jest to ORMHeavy @ Matthias. Niektórzy ludzie narzekają na rozmiar kodu i niektóre jego brakujące funkcje ... – Gray

+0

Dobra, wystarczy. Myślę, że to dziwne zaniedbanie, chociaż jest tak wiele innych funkcji. Jest to powszechny wzorzec antykoncepcyjny i - jak sądzę - niejako pokonuje własny cel, ponieważ wymaga, aby klient sam wykonał mapowanie, chyba że chce połknąć dodatkowy koszt tego (który jest duży i rośnie wraz z rozmiarem stołu) – Matthias

0

Nie dołącza są obsługiwane w ORMLite https://stackoverflow.com/a/7320091/323128 Jednak this reference da wizję sposobu, aby zakończyć zadanie

+0

Mam w porządku pracę z zapytaniami nieprzetworzonymi w tym przypadku.Czy można uzyskać listę z surowego zapytania? Lub mogę pracować tylko z GenericRawResults? – itmartins

+0

DOC: queryRaw metody zwracają obiekt GenericRawResults, który reprezentuje wynik jako tablica łańcuchów, tablica obiektów lub obiektów odwzorowanych przez użytkownika - Możesz więc zbudować obiekt kompozycji, który będziesz mapował na swoim wyniku, aby uzyskać jakieś dane pojemnika lepiej niż tablica ciągów – Maxim

+0

Dzięki Maxim, byłeś bardzo pomocny. Jednak moja aktualna klasa zamówień ma ponad 20 atrybutów, co bardzo utrudnia zamapowanie każdego atrybutu w celu uzyskania obiektu zamówienia. – itmartins