Where query in android

Урок 8. Room. Query

В этом уроке поговорим подробнее про Query. В каком виде мы можем получать данные: List, массив, Cursor, LiveData. Как передавать параметры. Как получать только некоторые поля. Как с помощью Query выполнять update и delete запросы в Room.

Полный список уроков курса:

В качестве примера будем работать с таким Entity классом:

List, массив, Cursor

Чтобы запросить из базы Employee-объекты, необходимо в Dao создать метод с аннотацией Query

В Query прописываем запрос, который должен вернуть данные. А в качестве возвращаемого типа указываем List .

При вызове этого метода, Room сделает запрос в таблицу employee, конвертирует полученные данные в Employee объекты и упакует их в List.

Запрос, который вы указываете в Query проверяется на правильность синтаксиса во время компиляции. Если в нем будет ошибка, система вам сразу подскажет это.

Вместо List, мы также можем использовать массив:

и даже Cursor, если это необходимо по каким-то причинам:

LiveData

Room умеет возвращать данные в LiveData обертке.

Получение данных в коде Activity выглядит так:

Получаем LiveData и подписываемся на него.

Использование LiveData имеет огромное преимущество перед использование списка или массива. Подписавшись на LiveData, вы будете получать свежие данные при их изменении в базе. Т.е. при добавлении новых, удалении старых или обновлении текущих данных в таблице employee, Room снова выполнит ваш Query запрос, и вы получите в onChanged методе актуальные данные с учетом последних изменений. Вам больше не надо самим запрашивать эти данные каждый раз. И все это будет приходить вам в UI поток.

Передача параметров

В Query можно передавать параметры, чтобы сделать запросы более конкретными.

Например, запрос данных по id

Перед параметром employeeId в запросе должно стоять двоеточие. Room возьмет значение этого параметра из метода и подставит его в запрос.

Рассмотрим еще несколько примеров:

Поиск сотрудников с зарплатой больше заданного значения

Поиск сотрудников с зарплатой в заданном диапазоне

Поиск сотрудников по имени или фамилии

Поиск сотрудников по списку id.

Subsets

Часто при запросе данных нам нужно получить из таблицы не все поля, а только некоторые. Такие запросы быстрее и легче, чем тянуть все поля.

Допустим нам надо получать только имя и фамилию сотрудника. Если сделать так:

то уже при компиляции получим ошибку: The columns returned by the query does not have the fields [id,salary] in Employee even though they are annotated as non-null or primitive. Columns returned by the query: [first_name,last_name].

Room сообщает, что в данных, которые вернет этот запрос, не хватает полей, чтобы заполнить все поля объекта Employee.

В этом случае мы можем использовать отдельный объект.

Обратите внимание, что он не Entity. Это обычный класс. С помощью ColumnInfo мы настраиваем имена полей, чтобы они совпадали с полями таблицы.

Используем этот класс в методе запроса:

Теперь все ок, и мы получим список Name объектов.

Вы также можете в этих не Entity классах использовать вложенные классы с аннотацией @Embedded. Подробно об этой аннотации мы говорили в Уроке 6.

insert, update и delete запросы

Аннотации Insert, Update и Delete позволяют нам модифицировать данные, но их возможности слишком ограниченны. Часто возникает необходимость обновить только некоторые поля или удалить записи по определенному условию. Это можно сделать запросами с помощью Query.

Читайте также:  Почему андроид не принимает входящие вызовы

Давайте рассмотрим пару примеров.

Обновление зарплат у сотрудников по списку id.

Опционально метод может возвращать int значение, в котором мы получим количество обновленных строк. Если вам это не нужно, то делайте метод void.

Вызов метода будет выглядеть так:

Удаление сотрудников по списку id

Запросы удаления также могут возвращать int значение, в котором мы получим количество удаленных строк.

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Полный список

— подробно разбираем метод чтения данных query
— используем сортировку, группировку, условия, having

На прошлых уроках мы использовали метод query для чтения всех данных из таблицы. Мы использовали только имя таблицы в качестве входного параметра и получали все записи. Но у query есть и другие параметры:

columns – список полей, которые мы хотим получить
selection – строка условия WHERE
selectionArgs – массив аргументов для selection. В selection можно использовать знаки ?, которые будут заменены этими значениями.
groupBy — группировка
having – использование условий для агрегатных функций
orderBy — сортировка

Попробуем на примере их использовать. Создадим приложение – справочник стран. Возьмем десять стран и сохраним в БД их наименование, количество населения и регион. Реализуем в приложении следующие функции:

— вывод всех записей
— вывод значения агрегатной функции (SUM, MIN, MAX, COUNT)
— вывод стран с населением, больше чем указано
— группировка стран по региону
— вывод регионов с населением больше, чем указано
— сортировка стран по наименованию, населению или региону

Выводить все данные снова будем в лог.

Project name: P0361_SQLiteQuery
Build Target: Android 2.3.3
Application name: SQLiteQuery
Package name: ru.startandroid.develop.p0361sqlitequery
Create Activity: MainActivity

Открываем layout-файл main.xml и пишем:

6 кнопок – 6 функций, которые мы планируем реализовать. Поля для ввода значений, где это необходимо. Для сортировки используем RadioGroup.

Код для MainActivity.java:

Никаких проверок на вводимые с экрана значения я не делал, чтобы не перегружать код. Он и так немаленький получился, но ничего сложного в нем нет.

Три массива данных name, people, region. Это наименования стран, их население (в млн.) и регионы, к которым страны относятся. По этим данным мы будем заполнять таблицу.

В методе onCreate мы определяем и находим экранные элементы, присваиваем обработчики, создаем объект dbHelper для управления БД, подключаемся к базе и получаем объект db для работы с БД, проверяем наличие записей в таблице, если нет ничего – заполняем ее данными, закрываем соединение и эмулируем нажатие кнопки Все записи — чтобы сразу вывести весь список.

В методе onClick – подключаемся к базе, читаем данные с экранных полей в переменные, описываем переменные, которые будем использовать в методе query, и курсор, и смотрим, какая кнопка была нажата.

btnAll – вывод всех записей. Вызываем метод query с именем таблицы и null для остальных параметров. Это уже знакомо, делали на прошлом уроке.

btnFunc – вывод значения агрегатной функции (или любого поля). Использую параметр columns, в который надо записать поля, которые я хотел бы получить из таблицы, т.е. то, что обычно перечисляется после слова SELECT в SQL-запросе. columns имеет тип String[] – массив строк. Создаем массив из одного значения, которое считано с поля etFunc на экране. Запускаем query.

Читайте также:  Android floatingactionbutton icon color

btnPeople – вывод стран с населением больше введенного на экране количества. Используем selection для формирования условия. При этом используем один аргумент — ?. Значение аргумента задаем в selectionArgs – это sPeople – содержимое поля etPeople. Запускаем query.

btnGroup – группировка стран по регионам и вывод общее количество населения. Используем columns для указания столбцов, которые хотели бы получить – регион и сумма населения. В groupBy указываем, что группировка будет по региону. Запускаем query.

btnHaving – вывод регионов с населением больше указанного числа. Полностью аналогично случаю с группировкой, но добавляется условие в параметре having – сумма населения региона должна быть меньше sRegionPeople (значение etRegionPeople с экрана).

btnSort – сортировка стран. Определяем какой RadioButton включен и соответственно указываем в orderBy поле для сортировки данных. Запускаем query.

В выше описанных случаях мы запускали query и получали объект c класса Cursor. Далее мы проверяем, что он существует и в нем есть записи (moveToFirst). Если все ок, то мы запускаем перебор записей в цикле do … while (c.moveToNext()). Для каждой записи перебираем названия полей (getColumnNames), получаем по каждому полю его номер и извлекаем данные методом getString. Формируем список полей и значений в переменную str, которую потом выводим в лог. После всего этого закрываем соединение.

Ну и в конце кода идет описание вложенного класса DBHelper. Тут ничего не изменилось с прошлых уроков. Только при создании таблицы используются другие поля.

Сохраняем все и запускаем приложение.

В лог при запуске вывелись все записи, как если бы мы нажали кнопку «Все записи».

— Все записи —
name = Китай; people = 1400; region = Азия;
name = США; people = 311; region = Америка;
name = Бразилия; people = 195; region = Америка;
name = Россия; people = 142; region = Европа;
name = Япония; people = 128; region = Азия;
name = Германия; people = 82; region = Европа;
name = Египет; people = 80; region = Африка;
name = Италия; people = 60; region = Европа;
name = Франция; people = 66; region = Европа;
name = Канада; people = 35; region = Америка;

Т.е. таблица заполнена данными, можно работать.

Попробуем использовать агрегатную функцию. Например – получим кол-во записей. Вводим значение:

жмем кнопку Функция. Смотрим лог:

— Функция count(*) as Count —
Count = 10;

Все верно, 10 записей в таблице.

Покажем страны с населением больше 100 млн. Вводим 100 и жмем Население >

— Население больше 100 —
name = Китай; people = 1400; region = Азия;
name = США; people = 311; region = Америка;
name = Бразилия; people = 195; region = Америка;
name = Россия; people = 142; region = Европа;
name = Япония; people = 128; region = Азия;

Сгруппируем страны по региону и покажем население регионов. Нажмем кнопку Население по региону

— Население по региону —
region = Азия; people = 1528;
region = Америка; people = 541;
region = Африка; people = 80;
region = Европа; people = 350;

Теперь отобразим только те регионы, в которых население выше 500 млн.чел. Вводим 500 и жмем Население по региону >

— Регионы с населением больше 500 —
region = Азия; people = 1528;
region = Америка; people = 541;

Осталась сортировка. Выберем, например, сортировку по населению и жмем кнопку Сортировка

— Сортировка по населению —
name = Канада; people = 35; region = Америка;
name = Италия; people = 60; region = Европа;
name = Франция; people = 66; region = Европа;
name = Египет; people = 80; region = Африка;
name = Германия; people = 82; region = Европа;
name = Япония; people = 128; region = Азия;
name = Россия; people = 142; region = Европа;
name = Бразилия; people = 195; region = Америка;
name = США; people = 311; region = Америка;
name = Китай; people = 1400; region = Азия;

Читайте также:  Android app and xml

По умолчанию сортировка идет по возрастанию.

Все работает так, как и должно. На этих примерах мы использовали все основные параметры метода query. Кроме описанных параметров, у метода query есть также реализации с использованием параметров limit и distinct. Я не стал их здесь отдельно показывать. Расскажу на словах:

limitстроковый параметр, указывается в формате [offset], rows. Т.е. если в query в качестве limit передать строку «5» — то запрос выдаст только пять первых записей. Если же передать «3,5«, то запрос выдаст пять записей, начиная с четвертой (НЕ с третьей).

distinct – это boolean-параметр, удаление дубликатов. Может быть true или false.

Надеюсь, что метод query, который сначала казался большим скоплением параметров, стал понятен и прост.

На следующем уроке:

— читаем данные из связанных таблиц
— используем rawQuery

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Android SQLite SELECT Query

I have taken String value from a EditText and set it inside SELECT QUERY after WHERE condition

But it doesn’t work. Any suggestions?

6 Answers 6

Try trimming the string to make sure there is no extra white space:

Also use c.moveToFirst() like @thinksteep mentioned.

This is a complete code for select statements.

Try using the following statement:

Cursor c = db.rawQuery(«SELECT * FROM tbl1 WHERE name = ?», new String[] );

Android requires that WHERE clauses compare to a ?, and you then specify an equal number of ? in the second parameter of the query (where you currently have null).

And as Nambari mentioned, you should use c.moveToFirst() rather than c.moveToNext()

Also, could there be quotations in name? That could screw things up as well.

Here is the below code.

where id is the condition on which result will be displayed.

this is my code to select one user and one only so you initiate an empty object of your class then you call your writable Database use a cursor in case there many and you need one here you have a choice Use : 1-

and don’t forget in case the database is empty you’ll have to deal with that in my case i just return an empty object

Good Luck

selectionArgs : this takes the ‘name’ you desire to compare with, as argrument.

Here note «A Cursor object, which is positioned before the first entry of the table you refer to».

So,to move to first entry :

getColumnIndex(String ColumnName) : this returns the zero-based column index for the given column name.

In case, you want to go searching through multiple rows for a given name under ‘name’ column then use loop as below:

Источник

Оцените статью