Как передать имя столбца в качестве параметра в базе данных комнаты? [дубликат]

Dec 11 2020

Я использую, roomdatabaseи у меня есть много категорий для запроса.

@Query("SELECT * FROM Table_name WHERE sweets = 1")
LiveData<List<Item>> getAllSweets();

@Query("SELECT * FROM Table_name WHERE drinks = 1")
LiveData<List<Item>> getAllDrinks();

Итак, вопрос в том, можно ли сделать один универсальный запрос и передать имя столбца в качестве параметра? Например:

@Query("SELECT * FROM Table_name WHERE :columnname = drinks AND :columnname = 1")
LiveData<List<Item>> getAllDrinks(String drinks); 

Я знаю, что я ссылаюсь на columnName, но если columnName имеет тип, intэто не должно быть?

LiveData<List<Item>> getAllDrinks(int drinks)

Ответы

Zain Dec 11 2020 at 22:23

Краткий ответ: вы не можете этого сделать, потому что SQLite этого не позволяет, проверьте здесь .

Длинный ответ:

У вашей модели есть пара недостатков:

  1. Модель проектирования базы данных: не то, чтобы дизайн базы данных был хорошим с точки зрения нормализации данных ; Почему? У вас есть столбец для sweets, другой для drinks, может быть, один для meals... Больше столбцов означает больше хранилища данных, больше полей с нулевым значением в записях, и вам нужен метод базы данных для запроса каждого столбца отдельно (например, о чем ваш вопрос)
  2. Наличие переменного имени столбца может быть подвержено ошибкам: что, если вы передадите столбец, которого нет в базе данных. Это одна из функций, Roomпредоставляемых вам по сравнению с абстрактным, SQL queriesгде Room предоставляет вам ошибки времени компиляции для неправильные имена столбцов, в то время как нормальный SQLite вызывает их во время выполнения.

Что я рекомендую вам делать:

Создайте единственный столбец, в котором указывается тип еды; для эффективности вы можете создать его типа intи сопоставить каждое целочисленное значение с определенным типом еды:

1 >> goes for >> sweats 
2 >> goes for >> drinks
and so on..

Теперь у вас есть один столбец (а не несколько, как в вашей модели) .Теперь у вас может быть один метод DAO для доступа к любому типу (о котором вы просили)

@Query("SELECT * FROM Table_name WHERE :foodtype = type")
LiveData<List<Item>> getAllDrinks(int type) // add the type

Примечание. Также для удобства чтения вы можете использовать Enum's в своих полях и преобразовывать типы комнат.