ORMLite JOINs o mapeo automático de rawQuery
Estoy buscando una manera de hacer una consulta que requiera una JOIN. ¿Hay alguna manera de hacer esto en una declaración preparada, o es el rawQuery
la única opción que tengo. Si rawQuery
es la única opción, entonces hay alguna forma de asignar automáticamente los objetos devueltos a los objetos de la Dao que se están implementando.
He cavado a través de los documentos y ejemplos, pero no puedo encontrar nada que me permitirá asignar el resultado de la base de datos en bruto a una clase de objeto ORM.
- ¿Cómo conectarse a una solicitud pendiente con RoboSpice (Splash> Actividad principal)?
- ORMLite ForeignCollection: ¿Debe usar ClosableIterator?
- Excepción al intentar crearOrUpdate un objeto utilizando OrmLite
- Consulta compleja con SQL COUNT y SUM
- Cómo utilizar correctamente claves foráneas en Android, utilizando SQLite y OrmLite
- ORMLite insertar o reemplazar
- Android, Ormlite, ubicación de DB
- Método de cadena de escape Ormlite?
- ¿Dónde encuentro el ApplicationContext necesario para inicializar ORMLite?
- Proguard con la colección parametrizada orrmlite
- Guardando colecciones de niños con OrmLite en Android con objetos creados de Jackson
- ORMLite - CallBatchTasks () individualmente o una vez para todas las actualizaciones?
- La función Android andmlite like () no funciona
ORMLite soporta simples consultas JOIN . También puede utilizar raw-queries para lograr esto.
Puede utilizar Dao.getRawRowMapper()
para asignar las consultas como lo encontró o puede crear un asignador personalizado. La documentación tiene el código de ejemplo siguiente que muestra cómo asignar la String[]
en su objeto:
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])); } });
He encontrado una manera de asignar automáticamente un conjunto de resultados a un objeto modelo.
// 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();
La clave es tirar del mapeador de filas de su objeto Dao
usando getRawRowMapper()
, que manejará la asignación para usted. Espero que esto ayude a cualquiera que lo encuentre.
Todavía me encantaría la posibilidad de hacer una QueryBuilder
dentro de QueryBuilder
pero hasta que se apoye, esta es la siguiente mejor cosa en mi opinión.
Asignación automática de consultas en bruto
Tenía problema de los campos de la correspondencia de SELECT de encargo que devuelven las columnas que no están presentes en ningún modelo de la tabla. Así que he hecho RawRowMapper
personalizado que puede asignar los campos de consulta personalizada a modelo personalizado. Esto es útil cuando tiene una consulta que tiene campos que no corresponde a ningún modelo de asignación de tabla.
Se trata de RowMapper que realiza la asignación automática de consultas:
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; } } }
Y aquí está el uso :
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()
Esto devolverá List<Model>
con filas de resultado asignadas a Modelo si los nombres de columnas de consulta y @DatabaseField(columnName
son iguales
- Descomprimir archivo en activos de Android
- Enviar valores de la actividad ViewPager a un fragmento por paquete