tutorial studio room library example android android-room

studio - room library android



Hardcode Boolean Query In Room Database (2)

Estoy creando una aplicación para Android que muestra una lista de posibles coincidencias para un usuario. El usuario puede hacer clic en uno para agradar al usuario, y guardo todos esos "me gusta" localmente.

Puedo escribir una consulta para obtener la lista de coincidencias como esta:

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit") fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

He aprendido que esto funciona bien. Sin embargo, no preveo ningún escenario en el que alguna vez establezca " liked en falso, ¿y por eso tengo curiosidad si hay una manera de codificar mi condición booleana? Si lo intento

@Query("SELECT * FROM match WHERE liked = true ORDER BY match DESC LIMIT :limit")

Recibo el siguiente error en tiempo de compilación:

Error:(8, 0) Gradle: error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: true)

¿Cómo puedo codificar este booleano en mi cadena de consulta?

También he intentado:

  • Envolviendo la condición en comillas simples
    • @Query("SELECT * FROM match WHERE liked = ''true'' ORDER BY match DESC LIMIT :limit")

El enfoque de CommonWare funciona y también responde la pregunta de los OP directamente; sin embargo, no soy un fan de hacer tal suposición sobre la base de datos. El supuesto debe ser seguro, pero puede crear un trabajo inesperado en el futuro si Room decide cambiar su implementación booleana.

Yo sugeriría que el mejor enfoque es no codificar el booleano 1 o 0 en la consulta. Si la base de datos está detrás de un repositorio, todavía es posible que el repositorio exponga una API elegante. Personalmente, creo que proteger el código base más grande de la implementación de la base de datos es algo bueno de todos modos.

Método Dao (copiado de la pregunta de OP)

@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit") fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>

Repositorio

class Repository { public Flowable<List<Match>> getLikedMatches() { return dao.getMatches(6, true); } }

Por supuesto, esta es una opción de opinión ya que asume un cierto estilo arquitectónico. Sin embargo, no hace suposiciones sobre la base de datos interna. Incluso sin el repositorio que protege la base de datos, la llamada se puede realizar en la base de datos pasando a todas partes, también sin hacer suposiciones sobre los datos subyacentes.


SQLite no tiene un tipo de datos booleano. Room lo asigna a una columna INTEGER , mapeando true a 1 y false a 0 .

Entonces, espero que esto funcione:

@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")

Tenga en cuenta que este comportamiento no está documentado. Sin embargo, no debería cambiar, al menos no sin que suenen los klaxons de alarma, ya que tendríamos que usar migraciones para lidiar con cualquier cambio.