ORMLite JOINs или автоматическое сопоставление rawQuery

Я ищу способ сделать запрос, который требует JOIN. Есть ли способ сделать это в подготовленном заявлении или является единственным параметром rawQuery который у меня есть. Если rawQuery – единственная опция, то есть какой-то способ автоматически отображать возвращенные объекты на объекты Дао, которые будут реализованы.

Я прорыл документы и примеры, но не могу найти ничего, что позволит мне сопоставить результат исходной базы данных с классом объектов ORM.

ORMLite поддерживает простые запросы JOIN . Вы также можете использовать raw-запросы для этого.

Вы можете использовать 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])); } }); 

Я нашел способ автоматической привязки результирующего набора к объекту модели.

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

Ключ состоит в том, чтобы вытащить преобразователь строк из вашего объекта Dao с помощью getRawRowMapper() , который будет обрабатывать отображение для вас. Надеюсь, это поможет любому, кто его найдет.

Мне все равно понравится возможность делать соединения внутри QueryBuilder но пока это не будет поддержано, это, на мой взгляд, следующая лучшая вещь.

Автоматическое сопоставление исходного запроса

У меня возникла проблема с отображением полей из пользовательского SELECT, которые возвращают столбцы, отсутствующие в любой модели таблицы. Поэтому я создал пользовательский 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> с отображенными результирующими строками в Model, если имена столбцов запроса и @DatabaseField(columnName одинаковы