Жесткий код Логический запрос в базе данных
Я создаю приложение для Android, которое отображает список потенциальных совпадений для пользователя. Пользователь может нажать на один, чтобы понравиться пользователю, и я сохраняю все эти локальные локальные.
Я могу написать запрос, чтобы получить список таких совпадений:
@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>
Я узнал, что это работает отлично. Тем не менее, я не предвижу какой-либо сценарий, когда мне когда-нибудь liked
false, и поэтому мне любопытно, есть ли способ жестко кодировать мое логическое состояние? Если я попробую:
@Query("SELECT * FROM match WHERE liked = true ORDER BY match DESC LIMIT :limit")
Во время компиляции я получаю следующую ошибку:
Error:(8, 0) Gradle: error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: true)
Как я могу скопировать этот Boolean в строку запроса?
Я также пробовал:
- Объединение условия в одинарные кавычки
-
@Query("SELECT * FROM match WHERE liked = 'true' ORDER BY match DESC LIMIT :limit")
Ответы
Ответ 1
SQLite не имеет логического типа данных. Комната сопоставляет его с столбцом INTEGER
, отображая true
для 1
и false
- 0
.
Поэтому я бы ожидал, что это сработает:
@Query("SELECT * FROM match WHERE liked = 1 ORDER BY match DESC LIMIT :limit")
Имейте в виду, что это поведение недокументировано. Тем не менее, он не должен меняться - по крайней мере, не без тревожного зондирования, - так как нам нужно будет использовать миграции, чтобы справляться с любыми изменениями.
Ответ 2
Подход CommonWare работает, а также напрямую отвечает на вопрос OPs; однако я не являюсь поклонником такого предположения о базе данных. Это предположение должно быть безопасным, но оно может создать неожиданную работу по дороге, если Room когда-либо решит изменить ее логическую реализацию.
Я бы предложил, чтобы лучший подход заключался в том, чтобы не перекодировать логический 1 или 0 в запрос. Если база данных находится за репозиторием, репозиторий по-прежнему может выставлять изящный API. Лично я считаю, что защищать большую базу кода от реализации базы данных все равно хорошо.
Метод Дао (скопирован из вопроса ОП)
@Query("SELECT * FROM match WHERE liked = :liked ORDER BY match DESC LIMIT :limit")
fun getMatches(limit: Int = 6, liked: Boolean = true): Flowable<List<Match>>
вместилище
class Repository {
public Flowable<List<Match>> getLikedMatches() {
return dao.getMatches(6, true);
}
}
Конечно, это упрямый вариант в том, что он предполагает определенный архитектурный стиль. Однако он не делает предположений о внутренней базе данных. Даже без защитного хранилища базы данных вызов может быть внесен в базу данных, передавая всюду всюду - также без предположений относительно базовых данных.