Рубрики
Без рубрики

Корневая база данных Android

Вступление Эта серия будет посвящена основам базы данных SQLite. I… С тегами java, android, новички, тристан.

Android (Серия из 20 частей)

  • Эта серия будет посвящена основам базы данных SQLite. Я буду следовать официальному руководству Google, ЗДЕСЬ но я буду работать в том порядке, который имеет для меня больше смысла.

Прежде чем мы начнем

  • Этот раздел довольно насыщен потоками, поэтому, если вы не знакомы с потоками, я бы рекомендовал вам начать читать учебник по потокам Oracle ЗДЕСЬ и конец здесь
  • Я бы также рекомендовал посмотреть ЭТО видео о шаблоне Java singleton, потому что мы будем использовать этот шаблон в этом уроке.

Что такое база данных комнат?

  • Проще говоря, это слой абстракции поверх базы данных SQLite, который значительно упрощает работу с SQLite за счет внутренней обработки деталей реализации.

  • Когда мы создаем базу данных комнат, мы должны удовлетворять 3 условиям.

1): Класс должен быть снабжен аннотацией @Database , включающей массив сущностей, в котором перечислены все сущности данных, связанные с базой данных.

2): Класс должен быть абстрактным классом, который расширяет База данных комнат .

3): Для каждого класса DAO , связанного с базой данных, мы должны определить абстрактный метод, который имеет нулевые аргументы и возвращает экземпляр класса DAO.

  • С учетом сказанного мы можем вставить код и просмотреть его построчно
@Database(entities = {Word.class}, version = 1, exportSchema = false)
public abstract class WordRoomDatabase extends RoomDatabase {

    public abstract WordDAO WordDAO(); 

    private static volatile WordRoomDatabase INSTANCE;
    private static final int NUMBER_OF_THREADS = 4;
    static  final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

    static WordRoomDatabase getDatabase(final Context context){
        if(INSTANCE == null){
            synchronized (WordRoomDatabase.class){
                if (INSTANCE == null){
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            WordRoomDatabase.class,"word_database")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

  • Этот код может показаться сложным, и так оно и есть, но не волнуйтесь, мы будем действовать медленно и переходить строка за строкой.

@База данных(сущности = {Word.class },,)

  • База данных @(сущности = {Word.class } является частью обязательного кода, который мы должны включить для правильной работы библиотеки комнат. @Database сообщает библиотеке комнат, что этот класс будет представлять нашу базу данных. сущности = {Word.class } является нашим массивом сущностей и используется для представления всех сущностей в нашей системе баз данных. версия,) имеет отношение к миграции базы данных. Однако миграция базы данных – это немного чересчур для этого урока. Так что просто знайте, что мы используем их, чтобы избежать ошибок сборки.

общедоступный абстрактный класс Word База данных комнат расширяет базу данных комнат

  • Это просто обычное объявление класса, и мы используем расширения, чтобы указать, что база данных Room является суперклассом. Это обязательно для любого класса, который помечен @Database . Вы также должны отметить, что наш подкласс является абстрактным. Подкласс становится абстрактным, если он не реализует все абстрактные методы, унаследованные от родительского класса. Вы можете доказать это, если удалите аннотация и прочтете сообщения об ошибках.

публичный реферат Word doc Word doc()

  • Это также обязательно для нашего класса базы данных, фактически через наши Объекты доступа к данным (DAO) мы сможем взаимодействовать с базой данных. Этот метод также должен быть абстрактным, потому что Room будет обрабатывать реализации для нас.

частный статический изменяемый ЭКЗЕМПЛЯР базы данных Word Room;

  • Приватность проста, мы используем ее для обеспечения инкапсуляции и сокрытия информации. Он статичен, поскольку метод, который установит этот экземпляр, является статическим, статический метод может обращаться только к статическим переменным. Это ключевое свойство одноэлементного шаблона. Однако volatile немного сложнее и нам нужна некоторая справочная информация, чтобы полностью понять это.

Летучий

  • Когда мы помечаем переменную как изменчивую, она выполняет несколько действий, но ее основная цель – убедиться, что изменения этой переменной в одном потоке видны всем остальным потокам. Если бы мы не пометили эту переменную как изменчивую, мы могли бы получить ошибку согласованности памяти . Итак, теперь нам нужно поговорить об ошибках согласованности памяти

Ошибки согласованности памяти

  • Этот тип ошибки возникает, когда разные потоки имеют несогласованные представления о том, какими должны быть одни и те же данные.
  • Способ избежать подобных ошибок – установить связь происходит до . Этот тип отношений является просто гарантией того, что записи в память одним конкретным оператором видны другому конкретному оператору. Распространенный способ установить этот тип связи для переменной, которая изменяется в нескольких потоках, – объявить ее как изменчивую .

  • Поэтому в основном мы используем volatile для предотвращения ошибок согласованности памяти, устанавливая связь происходит до . Это позволяет всем потокам видеть текущее состояние и изменения переменной

частный статический конечный результат;

  • Это довольно стандартно, мы просто используем модификаторы для объявления переменной класса типа int, которая никогда не меняется, а затем мы устанавливаем ее значение равным 4.

статический конечный сервис-исполнитель.Новый фиксированный пул потоков(КОЛИЧЕСТВО ПОТОКОВ);

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

1) Прямое управление: создание и управление потоками просто создавайте экземпляр потока самостоятельно каждый раз, когда нашему приложению необходимо его инициировать. Как вы можете себе представить, это сложно и многословно.

2) Абстрактное управление потоками: для остальной части приложения передайте задание исполнителю. Этот исполнитель будет заниматься всем управлением потоками для нас. Мы используем эту технику.

  • Возвращаемый тип ExecutorService представляет собой интерфейс, который содержит методы для создания, отслеживания и уничтожения потоков. Исполнители – это класс, который предоставляет нам служебные методы для создания таких вещей, как фиксированный пул потоков . Говоря о пулах фиксированных потоков, давайте поговорим о пулах потоков.

Пулы потоков

  • Пулы потоков состоят из рабочих потоков, важно отметить, что рабочие потоки – это особый вид потоков. Они значительно меньше по объему памяти, чем обычный объект потока, поэтому затраты памяти ниже. Кроме того, рабочие потоки часто используются для выполнения асинхронных задач (для чего мы их используем).
  • Распространенный тип пула потоков называется пул фиксированных потоков (то, что мы используем). Этот тип пула потоков всегда имеет определенное количество запущенных потоков. Любой тип задач, переданных этому пулу, будет отправлен во внутреннюю очередь, в которой хранятся задачи всякий раз, когда их больше, чем количество активных потоков. Как только поток станет доступным, пул даст ему задание

  • Таким образом, в основном с помощью нашего заявления мы создаем фиксированный пул потоков, состоящий из 4 рабочих потоков, которые мы можем использовать и выполнять асинхронные задачи, которые будут взаимодействовать с нашей базой данных.

статическая база данных Word Room Получает базу данных (окончательный контекстный контекст)

  • Этот метод является одноэлементным шаблоном 101, поэтому я не буду вдаваться в него слишком подробно, но в основном он сконструирован так, чтобы возвращать только один экземпляр ЭКЗЕМПЛЯРА . Вы, вероятно, заметите ключевое слово синхронизированный и это тоже нуждается в некотором объяснении.

Синхронизированный

  • Когда потоки взаимодействуют друг с другом, они делают это, в первую очередь, путем совместного доступа к полям объектов, которые они используют. Этот способ общения чрезвычайно эффективен, однако он допускает два типа ошибок.

1): Ошибки согласованности памяти (Мы уже говорили об этом)

2): Интерференция потоков, это происходит, когда две операции в двух разных потоках заканчиваются на одних и тех же данных. Когда это происходит, потоки, как говорят, чередуются . Чередование потоков приводит к ошибкам согласованности памяти . Способ, которым мы справляемся с этим чередованием потоков, состоит в том, чтобы объявить наш метод как синхронизированный и это имеет два эффекта

1): Невозможно чередовать два вызова синхронизированного метода при работе с одним и тем же объектом. Когда один поток выполняет синхронизированный метод на объекте, все остальные методы на том же объекте должны ждать, пока он не будет завершен.

2): Когда синхронизированный метод завершается, он гарантирует, что изменения, внесенные в объект, будут видны всем другим потокам, выполняющим операции с этим объектом.

если (ЭКЗЕМПЛЯР)

  • Я не уверен на 100%, почему мы должны сделать двойную проверку, чтобы убедиться, что экземпляр равен нулю но я предполагаю, что это то, что мы должны сделать, работая с потоками. Однако, если экземпляр равен нулю, мы создадим нашу реальную базу данных. Для создания нашей базы данных мы используем метод Room.database Builder и мы предоставляем ему глобальный контекст, экземпляр нашего класса базы данных и имя, которое мы собираемся назвать нашей базой данных. Наконец, мы вызываем build(), чтобы фактически создать нашу базу данных и вернуть ЭКЗЕМПЛЯР . ЭКЗЕМПЛЯР теперь представляет нашу базу данных. Если экземпляр не равен нулю, то мы просто возвращаем экземпляр, это стереотипно для одноэлементного шаблона.

  • Благодаря этому мы успешно создали базу данных комнат.

  • Спасибо, что нашли время в свой рабочий день, чтобы прочитать этот мой пост в блоге. Если у вас есть какие-либо вопросы или сомнения, пожалуйста, прокомментируйте ниже или свяжитесь со мной по Твиттер .

Android (Серия из 20 частей)

Оригинал: “https://dev.to/theplebdev/android-room-database-5an”