Статья опубликована в рамках: XLVIII Международной научно-практической конференции «Научное сообщество студентов XXI столетия. ТЕХНИЧЕСКИЕ НАУКИ» (Россия, г. Новосибирск, 26 декабря 2016 г.)
Наука: Информационные технологии
Скачать книгу(-и): Сборник статей конференции
дипломов
РАЗРАБОТКА БИБЛИОТЕКИ ДЛЯ ЗАПРОСОВ К БАЗАМ ДАННЫХ В ANDROID-ПРИЛОЖЕНИЯХ
Одной из самых известных библиотек, используемых для разработки мобильных приложений для Android, является библиотека Retrofit [6], с помощью которой можно записывать REST-запросы в виде java-интерфейсов. Библиотека Retrofit удобна тем, что проста в использовании и позволяет сократить количество кода.
Кроме REST-запросов некоторым приложениям требуется делать SQL-запросы к базе данных. Для выполнения SQL-запросов требуется писать большое количество однотипного кода. Целью данной работы является создание библиотеки, позволяющей автоматизировать создание кода для выполнения таких запросов.
Для автоматизации создания кода использовался механизм Annotation Processing. Данный механизм состоит из аннотаций и процессора аннотаций, с помощью которого происходит генерация кода [3].
Разработанная библиотека RetroBase содержит две аннотации DBInterface
и DBQuery
, а также процессор аннотаций DBAnnotationProcessor
. С помощью аннотации DBInterface разработчик
отмечает интерфейс с методами-запросами к базе данных, а аннотация DBQuery используется для указания на
каждый метод-запрос. Методы-запросы могут иметь параметры, которые будут использованы в SQL-запросе. Количество и типы параметров метода должны соответствовать параметрам запроса, переданного в качестве параметра аннотации DBQuery
[1].
Тип возвращаемого значения метода-запроса зависит от выполняемого SQL-запроса. Если выполняется SQL-запрос типов INSERT, DELETE или UPDATE, типом возвращаемого значения метода должен быть void, так как такой SQL-запрос не возвращает результат. Если выполняется SQL-запрос типа SELECT, метод должен возвращать объект класса ResultSet, в котором будут содержаться результаты запроса
.
Пример интерфейса с методами-запросами к базе данных:
@DBInterface(url = SpendDB.URL, login = SpendDB.USER_NAME, password = SpendDB.PASSWORD)
@DBInterfaceRx
public interface SpendDB {
String USER_NAME = "postgres";
String PASSWORD = "1234";
String URL = "jdbc:postgresql://192.168.1.26:5432/spend";
@DBMakeRx(modelClassName = "com.qwert2603.retrobase_example.DataBaseRecord")
@DBQuery("SELECT * from spend_test")
ResultSet getAllRecords();
@DBMakeRx
@DBQuery("DELETE FROM spend_test WHERE id = ?")
void deleteRecord(int id) throws SQLException;
}
В приведенном примере определяется интерфейс с методами-запросами к базе данных. Данные для подключения к базе данных, а также текст SQL-запросов передаются в качестве параметров соответствующим аннотациям.
Во время компиляции выполняется процессор аннотаций DBAnnotationProcessor
. Таким образом, осуществляется генерация класса, реализующего интерфейс. Сгенерированный класс имеет имя *название_интерфейса* + Impl
.
При генерации класса-реализации интерфейса в него добавляется поле для соединения с базой данных, используя адрес, имя пользователя и пароль, переданные в качестве параметров аннотации DBInterface.
Далее создается реализация каждого метода интерфейса и объект запроса
для каждого метода-запроса. Текст запроса передается аннотации DBQuery
в качестве параметра.
Также выполняется проверка на то, может ли метод передавать исключения
. В случае если метод может передавать исключения
, они будут переданы из реализации метода. Если метод не может передавать исключения, они будут обработаны в реализации метода.
Для каждого параметра аннотированного метода генерируется выражение позволяющее передать значение данного параметра в объект запроса.
После того, как реализация интерфейса была сгенерирована, она записывается на диск средствами Annotation Processing. [2]
Также, разработанная библиотека RetroBase позволяет выполнять запросы к базе данных в реактивном стиле, используя популярную библиотеку RxJava.
Для поддержки RxJava в RetroBase были добавлены процессор аннотаций DBMakeRxAnnotationProcessor
и аннотации DBInterfaceRx
и DBMakeRx
. Класс, сгенерированный процессором аннотаций DBMakeRxAnnotationProcessor,
будет иметь имя *название_интерфейса* + Rx
, а также будет иметь открытый конструктор, принимающий объект интерфейса, аннотированного DBInterfaceRx
, которому он будет перенаправлять запросы, возвращая результат в реактивном стиле.
Для использования процессора аннотаций DBMakeRxAnnotationProcessor необходимо отметить интерфейс с методами-запросами к базе данных аннотацией DBInterfaceRx, а также
добавить к методам-запросам аннотацию DBMakeRx. Аннотация
DBMakeRx
принимает в качестве параметра название класса модели, возвращаемой запросом. Сгенерированный метод-обертка будет возвращать объект класса Observable<*класс модели*>
. При этом, если название класса модели не определено, сгенерированный метод будет возвращать объект класса io.reactivex.Completable
, что удобно для SQL-запросов типов INSERT, DELETE или UPDATE, для которых не требуется возвращение результата.
Единственным требованием к классу модели является наличие открытого конструктора, принимающего объект класса ResultSet
для создания экземпляров класса модели в методе-обертке.
Все исключения, которые будут переданы методом-запросом к базе данных, обрабатываются в методе-обертке и передаются подписчику Observable или Completable
.
Если необходимо выполнить запрос INSERT и получить идентификатор (id) созданной записи, получить количество строк, измененных в результате выполнения запроса UPDATE или узнать идентификаторы записей, которые были удалены запросом DELETE, можно добавить конструкцию returning id
в конец SQL-запроса и получить объект класса ResultSet
c искомыми идентификаторами. Например:
@DBMakeRx(modelClassName = "com.qwert2603.spenddemo.model.Id")
@DBQuery("UPDATE spend_test SET kind=?, value=?, date=? WHERE id=? returning id")
ResultSet updateRecord(String kind, int value, Date date, int id) throws SQLException;
Также потребуется простой класс Id, позволяющий получать идентификатор из объекта класса ResultSet.
В процессе выполнения данной работы была разработана библиотека, которая может быть использована при разработке приложений, выполняющих запросы к базе данных. Исходный код библиотеки с комментариями и рабочий пример приложения, использующего библиотеку RetroBase доступны на ресурсе Github [4], [5].
Список литературы:
- Шилдт Г. Java 8. Полное руководство. — Вильямс, 2016. — 1376 с.: ил. ISBN 978-5-8459-1918-2
- A Java API for generating .java source files [Электронный ресурс]. – Режим доступа: https://github.com/square/javapoet (дата обращения 17.11.2016)
- The 10-Step Guide to Annotation Processing in Android Studio [Электронный ресурс]. – Режим доступа:http://blog.stablekernel.com/the-10-step-guide-to-annotation-processing-in-android-studio (дата обращения 17.11.2016)
- RetroBase [Электронный ресурс]. – Режим доступа: https://github.com/qwert2603/RetroBase (дата обращения 17.11.2016)
- RetroBaseExample [Электронный ресурс]. – Режим доступа: https://github.com/qwert2603/RetroBaseExample (дата обращения 17.11.2016)
- Retrofit [Электронный ресурс]. – Режим доступа: https://square.github.io/retrofit/ (дата обращения 17.11.2016)
дипломов
Оставить комментарий