Boolesche Hardcode-Abfrage in der Raumdatenbank

Lesezeit: 5 Minuten

Ich baue eine Android-Anwendung, die eine Liste potenzieller Übereinstimmungen für einen Benutzer anzeigt. Der Benutzer kann auf einen klicken, um ihn zu mögen, und ich speichere alle diese Likes lokal.

Ich kann eine Abfrage schreiben, um die Liste der Übereinstimmungen wie folgt zu erhalten:

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

Ich habe gelernt, dass das gut funktioniert. Ich sehe jedoch kein Szenario voraus, in dem ich jemals untergehen werde liked zu false, und deshalb bin ich neugierig, ob es eine Möglichkeit gibt, meine boolesche Bedingung fest zu codieren? Wenn ich es versuche:

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

Ich erhalte beim Kompilieren folgenden Fehler:

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

Wie kann ich diesen booleschen Wert in meiner Abfragezeichenfolge fest codieren?

Ich habe auch versucht:

  • Einschließen der Bedingung in einfache Anführungszeichen
    • @Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")

SQLite hat keinen booleschen Datentyp. Raum ordnet es einem zu INTEGER Spalte, Zuordnung true zu 1 und false zu 0.

Also, ich würde erwarten, dass das funktioniert:

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

Beachten Sie, dass dieses Verhalten undokumentiert ist. Es sollte sich jedoch nicht ändern – zumindest nicht ohne Alarmhupen – da wir Migrationen verwenden müssten, um mit Änderungen fertig zu werden.

  • Das hat funktioniert, danke! Ich denke definitiv, dass dies in der Room-Dokumentation übersehen wurde.

    – AdamMc331

    9. Dezember 2017 um 16:56 Uhr

  • @AdamMc331: Besonders nach ihrer letzten Änderungsrunde würde ich argumentieren, dass die Room-Dokumentation in der Room-Dokumentation übersehen wurde. 🙁 Aber ich bin froh, dass es bei dir funktioniert!

    – CommonsWare

    9. Dezember 2017 um 16:59 Uhr

  • Nun, ich bin so weit damit gekommen! 😛

    – AdamMc331

    9. Dezember 2017 um 17:19 Uhr

  • Oh ja, die Raumdokumentation ist sehr spärlich … danke!

    – techfly

    16. Februar 2018 um 15:06 Uhr

  • Die Raumdatenbank generiert eindeutig 1 für Wahr und 1 für Falsch. Kaufen Sie, meine Abfragen geben null oder leere Listen zurück. Was könnte das Problem sein?

    – TheRealChx101

    14. Oktober 2019 um 21:58 Uhr

Der Ansatz von CommonWare funktioniert und beantwortet auch direkt die OP-Frage. Ich bin jedoch kein Fan davon, eine solche Annahme über die Datenbank zu treffen. Die Annahme sollte sicher sein, kann aber später zu unerwarteter Arbeit führen, wenn Room jemals beschließt, seine boolesche Implementierung zu ändern.

Ich würde vorschlagen, dass der bessere Ansatz darin besteht, die boolesche 1 oder 0 nicht in die Abfrage fest zu codieren. Wenn sich die Datenbank hinter einem Repository befindet, ist es für das Repository immer noch möglich, eine elegante API bereitzustellen. Ich persönlich denke, dass es sowieso eine gute Sache ist, die größere Codebasis von der Datenbankimplementierung abzuschirmen.

Dao-Methode (von OPs Frage kopiert)

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

Repository

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

Natürlich ist dies eine eigensinnige Option, da sie einen bestimmten architektonischen Stil voraussetzt. Es werden jedoch keine Annahmen über die interne Datenbank getroffen. Auch ohne das Repository, das die Datenbank abschirmt, kann der Aufruf in die Datenbank erfolgen, indem überall wahr übergeben wird – auch ohne Annahmen über die zugrunde liegenden Daten zu treffen.

  • Wenn Sie einen anderen Baustil verwenden. Sie können den Standardwert direkt in der DAO-Definition abschirmen. aber Sie müssen das DAO als abstrakte Klasse definieren, nicht als Schnittstelle. Gleiche Definition wie oben: @Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit") protected abstract fun getMatches(limit: Int, liked: Boolean): Flowable<List<Match>> und die öffentliche Version fun getLikedMatches(limit: Int = 6) = getMatches(limit, true)

    – Allmächtig

    13. Mai 2019 um 20:31 Uhr


  • “wenn Room jemals beschließt, seine boolesche Implementierung zu ändern” – sie dürfen dies nicht tun, da jeder vorhandene boolesche Daten beim Upgrade von Room “beschädigen” würde. Ich habe noch nie eine Datenmigrationslogik für Änderungen in der Raumbibliothek gesehen.

    – Der unglaubliche Jan

    6. Januar 2021 um 7:18 Uhr

  • “sie dürfen es nicht” – sie können. Sie tun es vielleicht langsam, aber sie können es absolut. Es kann gefährlich sein, sich auf die zugrunde liegende Implementierung von Room zu verlassen. Nur weil etwas aufgedeckt wird, reicht dies nicht als Rechtfertigung aus, es zu verwenden – insbesondere dann nicht, wenn das gleiche Ziel durch dokumentiertes Verhalten erreicht werden kann.

    – Methodensignatur

    16. Januar 2021 um 23:39 Uhr

  • “sie können”, aber es wäre ein Fehler. Ich kann auch Fehler programmieren, aber überraschenderweise mag das niemand.

    – Der unglaubliche Jan

    17. Mai 2021 um 8:23 Uhr

  • Eine Speicherbibliothek, die ihre interne Implementierung ändert, ist kein Fehler. Ich kann auch knapp sein, aber überraschenderweise mag das niemand.

    – Methodensignatur

    1. Oktober 2021 um 13:56 Uhr

Benutzer-Avatar
Dämon

Sie müssen die boolesche Spalte nicht mit einem Wert vergleichen. Verwenden Sie einfach den Spaltenwert selbst als booleschen Ausdruck. Sie können Ihre Abfrage ganz einfach in ändern SELECT * FROM match WHERE liked ORDER BY match DESC LIMIT :limit. Wenn Sie vergleichen möchten false Wert können Sie folgenden Ausdruck verwenden: where not liked.

@Query("SELECT * FROM searched_data_table WHERE favourit_history==1 ORDER BY lang_id DESC")

Verwenden Sie diese Abfrage, um Daten aus der Tabelle zu suchen. Dadurch erhalten Sie Daten in absteigender Reihenfolge in Bezug auf Ihren Schlüsselwert

1300570cookie-checkBoolesche Hardcode-Abfrage in der Raumdatenbank

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy