Как импортировать данные в базу данных Room при создании? - PullRequest
0 голосов
/ 06 августа 2020

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

    db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
            .addCallback(new RoomDatabase.Callback() {

                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);

                    // IMPORT DATA
                }
            })
            .build();

Однако при попытке фактически импортировать данные все усложняется. Когда я пытаюсь импортировать данные с помощью Entities, Daos и AppDatabase, я сталкиваюсь с исключением:

java .lang.IllegalStateException: getDatabase вызывается рекурсивно

It похоже, что невозможно импортировать данные в базу данных с использованием всех хороших объектов Room Entities, Daos и т. д. Однако метод onCreate предоставляет доступ к базовой базе данных SQLite. Может быть, я собираюсь импортировать туда данные?

Документация по использованию базы данных SQLite напрямую довольно тонкая. И он начинается с большого красного предупреждения, чтобы не обращаться к базе данных SQLite напрямую, а вместо этого использовать абстракции Room!

Что мне делать? Как это обычно делается?

Существуют ли таблицы, которые я определил с помощью Entities? Или мне нужно создать таблицы с операторами SQL, прежде чем я смогу начать импортировать свои данные?

1 Ответ

0 голосов
/ 07 августа 2020

Есть два основных способа импортировать данные в базу данных Room после создания. Первый использует уродливый обходной путь, но затем позволяет использовать объекты комнаты и все такое. Второй - работать напрямую с предоставленным экземпляром SQLiteDatabase.

1. Вставьте охранник и работайте с абстракциями комнаты

    final boolean[] doImport = { false };

    db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
            .addCallback(new RoomDatabase.Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);
                    doImport[0] = true;
                }
            })
            .build();

    db.userDao().get(17);

    if (doImport[0]) {
        UserEntity user = new UserEntity();
        user.name = "John Doe";
        db.userDao().insert(user);
    }

Логическое значение doImport служит защитой протокола, независимо от того, был ли вызван обратный вызов onCreate. Однако это должен быть массив, потому что новое значение не может быть присвоено простому логическому значению изнутри onCreate.

Обратите внимание на кажущуюся бессмысленной строку db.userDao().get(17);. Для вызова обратного вызова onCreate необходим доступ к базе данных. В противном случае doImport останется false на этом этапе, независимо от того, была ли база данных создана заново.

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

2. Работать напрямую с SQLiteDatabase

    db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
            .addCallback(new RoomDatabase.Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);

                    db.beginTransaction();
                    ContentValues values = new ContentValues();
                    values.put("name", "John Doe");
                    db.insert("UserEntity", SQLiteDatabase.CONFLICT_ABORT, values);
                    db.setTransactionSuccessful();
                    db.endTransaction();
                }
            })
            .build();

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

...