Научная статья на тему 'Манипуляция данными в мобильной СУБД Realm для Google Android'

Манипуляция данными в мобильной СУБД Realm для Google Android Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
503
94
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
СИСТЕМА УПРАВЛЕНИЯ БАЗАМИ ДАННЫХ / КЛАСС / ОБЪЕКТ / ЗАПРОС / АСИНХРОННАЯ ТРАНЗАКЦИЯ

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Смольянов Андрей Григорьевич

В статье описываются возможности манипулирования данными, организованными системой управления базами данных (СУБД), предназначенной для поддержки информационной части мобильных приложений. В статье кратко описываются разновидности операций, связанной с доступом к исходным данным и их обработкой.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Манипуляция данными в мобильной СУБД Realm для Google Android»

МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х

5. Ожегов, С. И. Толковый словарь русского языка / С. И. Ожегов, Н. Ю. Шведова. - М.: Азбуковник, 2000. - 940 с.

6. Пушников А.Ю. Введение в системы управления базами данных. Часть 1. Реляционная модель данных: Учебное пособие/Изд-е Башкирского ун-та. - Уфа, 1999. - 108 с. - ISBN 5-7477-0350-1

© Поддубная Л.В., 2016

УДК 004.9:519.688

Смольянов Андрей Григорьевич

к.ф.-м.н., зав. кафедрой фундаментальной информатики ФГБОУ ВО «МГУ им. Н.П. Огарёва»,

г. Саранск, РФ E-mail: [email protected] Ивановичев Вячеслав Валерьевич студент 4 курса факультета математики и информационных технологий ФГБОУ ВО «МГУ им. Н.П. Огарёва»,

г. Саранск, РФ E-mail: [email protected]

МАНИПУЛЯЦИЯ ДАННЫМИ В МОБИЛЬНОЙ СУБД REALM ДЛЯ GOOGLE ANDROID

Аннотация

В статье описываются возможности манипулирования данными, организованными системой управления базами данных (СУБД), предназначенной для поддержки информационной части мобильных приложений. В статье кратко описываются разновидности операций, связанной с доступом к исходным данным и их обработкой.

Ключевые слова

Система управления базами данных, класс, объект, запрос, асинхронная транзакция.

В статье [1] были изложены вводные сведения о системе управления базами данных Realm. Настоящий материал является продолжением указанной статьи, в котором продолжено краткое обсуждение возможностей Realm, связанных с манипулированием данными в базе.

Для обзора основных возможностей по манипулированию данными кратко обсудим сам механизм запросов. Синтаксис запросов Realm использует так называемый Fluent Interface (пер. Текучий интерфейс), суть которого состоит в повышении читабельности исходного кода программы. Благодаря этому код запросов становится лаконичным и интуитивно понятным. Структура запросов выглядит следующим образом:

(экземпляр Realm).(критерий where).

(условия выборки).(fmdFirstO или findAll()).

Метод findFirst() дает возможность обнаружить в процессе запроса первое совпадение, метод findAll() позволяет получить полную выборку. Если по нужным условиям не удалось найти данные, то findFirst() вернет null, а findAll() - пустую коллекцию RealmResults.

Например, для того выбрать из Realm пользователя (класс User), чье имя совпадает с именем "Александр", достаточно написать код:

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

User user = realm.where(User.class)

.equalTo("name", "Александр")

.findFirst();

Переменная user содержит объект пользователя со всеми его данными. Теперь для получения списка заметок используется геттер:

RealmList<Note> notes = user.getNotes(); Результат выборки показан на рисунке 1.

,.|| 100% И 14:15

RealmNotes

Александр 1

Заметка 1 Александра Fri Feb 19 12:29:20 GMT+03:00 2016

2

Заметка 2 Александра Fri Feb 19 12:29:20 GMT+03:00 2016

Рисунок 1 - Результат выборки данных

Другой вариант выборки не обращаться к связной модели, а напрямую выполнить следующий код, результат которого полностью эквивалентен предыдущему: RealmResults<Note> notes = realm.where(Note.class).equalTo("user.name", "Александр").findAllO;

Этот запрос означает следующее: выбрать из Realm все заметки (класс Note), в которых в связной модели (класс User) имя совпадает с именем "Александр". Кроме того, результатом данной выборки будет коллекция RealmResults, которая является подклассом Java-класса AbstractList и хранит ссылки на объекты Notes. Заметим важный факт: Realm не копирует выбранные объекты, а возвращает ссылки на оригинальные объекты из хранилища.

Чтобы достать заметки Вячеслава, следует всего лишь изменить имя в методе .equalTo(); User user = realm.where(User.class) .equalTo("name", "Вячеслав") .findFirst();

Для того чтобы добавить больше заметок пользователю "Вячеслав" (на данный момент 2 заметки), требуется открыть транзакцию с помощью метода beginTransaction(), выполнить добавление данных, применить транзакцию с помощью метода commitTransaction(): realm.beginTransaction(); try {

User user = realm.where(User.class) .equalTo("name", "Вячеслав") .findFirst(); int lastId =

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

realm.where(Note.class).findAll().max("id").intValue()

+ 1;

if (user.getNotes() != null) {

RealmList<Note> notes = user.getNotes();//количество 2 for (int i = 1; i <= 10; i++) { Note note = new Note(); note.setId(lastId + i); note.setDate(new Date()); note.setUser(user); note.setTitle (" Заметка Вячеслава"); note = realm.copyToRealm(note); notes.add(note);

}

realm.commitTransaction(); user.getNotes(); // количество 12

}

txtName.setText(user.getName()); } catch (Exception e) { e.printStackTrace(); realm.cancelTransaction();

}

Результат работы данного кода показан на рисунке 2.

Заметка 1 Вячеслава Заметка 2 Вячеслава Заметка Вячеслава Заметка Вячеслава

Рисунок 2 - Результат добавления данных

Заметить, что в данном коде бы использован так называемый агрегирующий метод - max(), предназначенный в нашем случае для выборки максимального id.

Realm позволяет использовать следующие агрегирующие методы:

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

1. results.sum("Поле").intValue()- сумма;

2. results.max("Поле").longValueO- максимальный элемент;

3. results.min("Поле").longValueO- минимальный элемент;

4. double average = results.average("Поле") - среднее;

5. results.matches()- количество совпадений.

Помимо .equalTo() Realm поддерживает следующие условия:

• between, greaterThan(), lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo()

• equalTo() & notEqualTo()

• contains(), beginsWith() & endsWith()

Строковые условия по умолчанию чувствительны к регистру, чтобы сделать условия не чувствительными к регистру нужно добавить модификатор CASE_INSENSITIVE.

К примеру, выберем те заметки, у которых дата публикации между 19 и 24 февраля 2016 года. GregorianCalendar calendar = new GregorianCalendar(); calendar.set(2016, Calendar.FEBRUARY, 18); Date dateMin = calendar.getTime(); calendar.set(2016, Calendar.FEBRUARY, 24); Date dateMax = calendar.getTime(); RealmResults<Note> n = realm.where(Note.class) .between("date",dateMin,dateMax) .findAll();

Результат выполнения кода показан на рисунке 3.

Заметки между 19 и 24 февраля

Заметка 2 Александра Fri Feb 19 17:45:34 GMT+03:00 2016

3

Заметка 1 Вячеслава Fri Feb 19 17:45:34 GMT+03:00 2016

4

Заметка 2 Вячеслава Fri Feb 19 17:45:34 GMT+03:00 2016

5

Заметка 1 Михаила_

Рисунок 3 - Результат выборки данных

Важное замечание: по умолчанию условия в Realm, соединенные точкой, соответствуют логической операции "И". Для того чтобы использовать "ИЛИ", условия следует объединять в группу, факторизованную скобками. Добавим к вышепоказанному примеру ограничения: выберем лишь те заметки, которые относятся к Александру или Михаилу, отсортируем их по id в порядке убывания, а интервал дат оставим прежним. Следующий код решает эту задачу.

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

GregorianCalendar calendar = new GregorianCalendar(); calendar.set(2016, Calendar.FEBRUARY, 18); Date dateMin = calendar.getTime(); calendar.set(2016, Calendar.FEBRUARY, 24); Date dateMax = calendar.getTime(); RealmResults<Note> n = realm.where(Note.class) .between("date", dateMin, dateMax) .beginGroup()

.equalTo("user.name", "Александр") or()

.equalTo("user.name", "Михаил") .endGroup() .findAll(); n.sort("id", Sort.DESCENDING);

В приведенном выше коде условие "ИЛИ" отделяется .beginGroup() и .endGroup(), что можно интерпретировать как операторные скобки. Результат работы кода показан на рисунке 4.

Заметки между 19 и 24

февраля

5

Заметка 1 Михаила Fri Feb 19 17:45:34 GMT+03:00 2016 2

Заметка 2 Александра Fri Feb 19 17:45:34 GMT+03:00 2016

1

Заметка 1 Александра Fri Feb 19 17:45:34 GMT+03:00 2016

Рисунок 4 - Результат выборки данных

Особо отметим коллекцию RealmResults<?>. Её преимущество состоит в том, что при изменении данных у моделей из этой коллекции запрос на получение обновленных значений писать не требуется заново - они обновляются на лету.

Кратко обсудим возможности асинхронных запросов.

По аналогии с асинхронной записью Realm поддерживает выборку данных в отдельном потоке. Как правило, запросы выполняются очень быстро, так что в простых случаях запросы можно запускать из UI потока. Для случаев, когда требуется построить сложный запрос с большой выборкой данных, использование отдельных потоков вполне оправдано. Например, следующий код выполнит выборку в отдельном потоке, а затем вернет полученные данные в главный поток: RealmResults<User> result = realm.where(User.class).findAllAsync();

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

Если требуется получить уведомление об успешном получении данных из другого потока, необходимо зарегистрировать слушатель RealmChangeListener и передать его в метод .addChangeListener(). Этот слушатель будет вызываться каждый раз когда объект RealmResults будет обновлен. К примеру, достанем все заметки и выведем их в ListView в виде - <заголовок заметки> <Автор>: ListView notesList = (ListView) findViewById(R.id.notesList); final Context context = this; RealmChangeListener callback =

new RealmChangeListener() { @Override

public void onChange() {

Toast.makeText(context, "Данные успешно получены",Toast.LENGTH_LONG) .show();

}

};

RealmResults<Note> result = realm.where(Note.class).findAllAsync();

result.addChangeListener(callback);

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

notesList.setAdapter

(new NotesAdapter(context, result)); Результат работы кода показан на рисунке 5.

Заметка 1 Вячеслава Вячеслав

Заметка 2 Вячеслава Вячеслав

Заметка 1 Михаила Михаил

За

Данные успешно получены

IVICI Г\ CI unlcCTlaDCl

Вячеслав

Рисунок 5 - Результат асинхронного запроса

Слушатель описывается с помощью метода

result.removeChangeListeners().

Отписаться от нужного слушателя позволяет метод

result.removeChangeListener(callback).

Удаление данных, как при выполнении записи в Realm, необходимо оборачивать в методы beginTransaction и commitTransaction(). Существуют несколько методов удаления данных из базы данных. К примеру, достанем из базы данных все заметки и применим к ним эти методы: RealmResults<Note> results =

realm.where(Note.class) .findAll(); В этих условиях:

1. results.removeLast()- удалит последний элемент коллекции RealmResults;

2. results.remove(0) - удалит элемент с индексом 0, т. е. первый элемент коллекции;

3. results.clear()- удалит все выбранные из базы данных объекты.

_МЕЖДУНАРОДНЫЙ НАУЧНЫЙ ЖУРНАЛ «СИМВОЛ НАУКИ» №6/2016 ISSN 2410-700Х_

4. note.removeFromRealm()- удалит объект из БД.

Исходя из рассмотренных основных возможностей данной системы управления базами данных, можно сделать вывод о том, что Realm является весьма мощным, быстрым и простым в использовании инструментом для разработки мобильных приложений любой сложности и тематической направленности.

Список использованной литературы 1. Смольянов А.Г., Ивановичев В. В. Краткий обзор мобильной СУБД Realm для Google Android. // Международный научный журнал «Символ науки». - 2016. - часть 4. - № 3. - с. 35-40.

© Смольянов А. Г., Ивановичев В. В., 2016

i Надоели баннеры? Вы всегда можете отключить рекламу.