В качестве основы можно использовать следующее (java, а не kotlin): -
CustomerWithOrders.java
public class CustomerWithOrders {
Customer customer;
List<Order> orders;
//<<<<<<<<<<< this constructor >>>>>>>>>>
public CustomerWithOrders(Customer customer, List<Order> orders) {
this.customer = customer;
this.orders = orders;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
}
в сочетании с (добавление между датамик предложению WHERE) (в PersonDao.java )
@Query("SELECT * FROM Orders WHERE customerId=:customerId")
abstract List<Order> getCustomerOrders(long customerId);
и затем используйте что-то вроде: -
List<Customer> allCustomers = mPDB.personDao().getAllCustomers(); //<<<<<<<< Get the required Customers (all in this example)
ArrayList<CustomerWithOrders> allCWO = new ArrayList<>(); //<<<<<<<<<< Empty CustomerWithOrders array
for (Customer c: allCustomers) {
allCWO.add(new CustomerWithOrders(c,mPDB.personDao().getCustomerOrders(c.getId()))); //<<<<<<<< tie the orders to the customer
}
//<<<<<<<<< for demo >>>>>>>>>>
String TAG = "CWOINFO";
StringBuilder sb = new StringBuilder();
for (CustomerWithOrders cwo: allCWO ) {
sb.append("\nCustomer is " + cwo.getCustomer().getName());
for (Order o: cwo.getOrders()) {
sb.append("\n\tOrder is " + o.getDescription());
}
}
Log.d(TAG,sb.toString());
Результат: (все заказы перечислены для проверки): -
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 1Description = Order1 for Customer1Cust ID = 1
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 2Description = Order2 for Customer1Cust ID = 1
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 3Description = Order3 for Customer1Cust ID = 1
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 4Description = Order1 for Customer2Cust ID = 2
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 5Description = Order2 for Customer2Cust ID = 2
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 6Description = Order3 for Customer2Cust ID = 2
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 7Description = Order4 for Customer2Cust ID = 2
2019-06-29 18:27:49.368 D/ORDERINFO: OrderID = 8Description = Order1 for Customer3Cust ID = 3
<<<<<<<<<< The output from the above code >>>>>>>>>>
2019-06-29 18:27:49.377 D/CWOINFO: Customer is Customer1
Order is Order1 for Customer1
Order is Order2 for Customer1
Order is Order3 for Customer1
Customer is Customer2
Order is Order1 for Customer2
Order is Order2 for Customer2
Order is Order3 for Customer2
Order is Order4 for Customer2
Customer is Customer3
Order is Order1 for Customer3
Альтернатива
Добавив следующий метод в CustomerWithOrders.java
public void addOrder(Order newOrder) {
this.orders.add(newOrder);
}
И добавив следующее в Dao: -
@Query("SELECT * FROM customers WHERE id=:customerId")
abstract Customer getCustomerById(long customerId);
@Query("SELECT * FROM orders LEFT JOIN customers ON orders.customerId = customers.id WHERE date BETWEEN :dateStart AND :dateEnd ORDER BY customerId")
abstract List<Order> getOrders(long dateStart, long dateEnd);
@Transaction
public List<CustomerWithOrders> getCustomersWithOrdersInDateRange(long dateStart, long dateEnd) {
List<Order> ordersWithCustomer = getOrders(dateStart,dateEnd);
ArrayList<CustomerWithOrders> cwo = new ArrayList<>();
long currentCustomerId = 0;
for (Order o: ordersWithCustomer) {
if (o.getCustomerId() != currentCustomerId) {
currentCustomerId = o.getCustomerId();
cwo.add(new CustomerWithOrders(getCustomerById(o.getCustomerId()),new ArrayList<Order>()));
}
cwo.get(cwo.size()-1).addOrder(o);
}
return cwo;
}
Вы можете использовать код в соответствии с: -
List<CustomerWithOrders> selectedCustomersWithOrders = mPDB.customerOrderDao().getCustomersWithOrdersInDateRange(0,99999999999999999L);
С LiveData (частичный пример)
Примечание не полностью протестированокак я обычно использую allowMainThreadQueries()
для ответов
@Query("SELECT * FROM orders LEFT JOIN customers ON orders.customerId = customers.id WHERE date BETWEEN :dateStart AND :dateEnd ORDER BY customerId")
abstract LiveData<List<Order>> getOrders(long dateStart, long dateEnd); //<<<<<<<<<<< LD
@Transaction
public List<CustomerWithOrders> getCustomersWithOrdersInDateRange(long dateStart, long dateEnd) {
LiveData<List<Order>> ordersWithCustomer = getOrders(dateStart,dateEnd); //<<<<<<<<<<< LD
ArrayList<CustomerWithOrders> cwo = new ArrayList<>();
long currentCustomerId = 0;
for (Order o: ordersWithCustomer.getValue()) { //<<<<<<<<<<< LD
if (o.getCustomerId() != currentCustomerId) {
currentCustomerId = o.getCustomerId();
cwo.add(new CustomerWithOrders(getCustomerById(o.getCustomerId()),new ArrayList<Order>()));
}
cwo.get(cwo.size()-1).addOrder(o);
}
return cwo;
}
- Комментарии указывают на изменения