Какова первоначальная миграция, настройка Room (SQLite) в существующем приложении? - PullRequest
0 голосов
/ 21 марта 2020

Я работаю над созданием небольшой базы данных SQLite в своем приложении, которая до сих пор хранит данные в OS MediaStore. Я хочу отойти от этого и использовать Room.

Исходная таблица очень проста, в основном это просто текстовое поле для описания и некоторые идентификаторы для реального изображения в MediaStore. Тем не менее, я хочу настроить еще несколько таблиц. Выглядит ли это несколько разумно:

import android.provider.BaseColumns;
import android.provider.MediaStore;

public class AlbumContract {

    public static class PhotoEntry implements BaseColumns {
        public static final String TABLE_NAME = "photo";
        public static final String COLUMN_NAME_IMAGE_ID = "fk_image_id";
        public static final String COLUMN_NAME_IMAGE_URI = "mediastore_uri";
        public static final String COLUMN_NAME_EVENT_ID = "fk_event_id";
        public static final String COLUMN_NAME_STACK_ID = "fk_stack_id";
        public static final String COLUMN_NAME_DESCRIPTION = "description";
    }

    public static class StackEntry implements BaseColumns {
        public static final String TABLE_NAME = "stack";
        public static final String COLUMN_NAME_STACK_LEADER = "fk_photo_id";
    }

    public static class EventEntry implements BaseColumns {
        public static final String TABLE_NAME = "event";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
        public static final String COLUMN_NAME_ALBUM_ID = "fk_album_id";
    }

    public static class AlbumEntry implements BaseColumns {
        public static final String TABLE_NAME = "album";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
    }

    public static final String SQL_CREATE_PHOTO =
            "CREATE TABLE " + PhotoEntry.TABLE_NAME + " (" +
                    PhotoEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    PhotoEntry.COLUMN_NAME_IMAGE_ID + " INTEGER, " +
                    PhotoEntry.COLUMN_NAME_IMAGE_URI + " TEXT, " +
                    PhotoEntry.COLUMN_NAME_STACK_ID + " INTEGER, " +
                    PhotoEntry.COLUMN_NAME_EVENT_ID + " INTEGER, " +
                    PhotoEntry.COLUMN_NAME_DESCRIPTION + " TEXT, " +
                    // Foreign key to MediaStore.Images
                    "FOREIGN KEY (" + PhotoEntry.COLUMN_NAME_IMAGE_ID + ") " +
                    "REFERENCES " + MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "(" + MediaStore.Images.Media._ID + ") " +
                    // Foreign key to "stack" table
                    "FOREIGN KEY (" + PhotoEntry.COLUMN_NAME_STACK_ID + ") " +
                    "REFERENCES " + StackEntry.TABLE_NAME + "(" + StackEntry._ID + ") " +
                    // Foreign key to "event" table
                    "FOREIGN KEY (" + PhotoEntry.COLUMN_NAME_EVENT_ID + ") " +
                    "REFERENCES " + EventEntry.TABLE_NAME + "(" + EventEntry._ID + ") " +
                    ")";

    public static final String SQL_CREATE_STACK =
            "CREATE TABLE " + StackEntry.TABLE_NAME + " (" +
                    StackEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    StackEntry.COLUMN_NAME_STACK_LEADER + " INTEGER " +
                    "FOREIGN KEY (" + StackEntry.COLUMN_NAME_STACK_LEADER + ") " +
                    "REFERENCES " + PhotoEntry.TABLE_NAME + "(" + PhotoEntry._ID + ") " +
                    ")";

    public static final String SQL_CREATE_EVENT =
            "CREATE TABLE " + EventEntry.TABLE_NAME + " (" +
                    EventEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    EventEntry.COLUMN_NAME_ALBUM_ID + " INTEGER, " +
                    EventEntry.COLUMN_NAME_TITLE + " TEXT, " +
                    EventEntry.COLUMN_NAME_SUBTITLE + " TEXT, " +
                    "FOREIGN KEY (" + EventEntry.COLUMN_NAME_ALBUM_ID + ") " +
                    "REFERENCES " + AlbumEntry.TABLE_NAME + "(" + AlbumEntry._ID + ") " +
                    ")";

    public static final String SQL_CREATE_ALBUM =
            "CREATE TABLE " + AlbumEntry.TABLE_NAME + " (" +
                    AlbumEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    AlbumEntry.COLUMN_NAME_TITLE + " TEXT, " +
                    AlbumEntry.COLUMN_NAME_SUBTITLE + " TEXT)";
}

Приложение позволяет пользователю сохранять подписи / описания к изображениям на устройстве, поэтому, если пользователь комментирует изображение, тогда идентификатор изображения + подпись сохраняется в photo Таблица. Существует отношение 1: n к таблице stack, где несколько изображений могут быть частью «стека». Кроме того, последовательности фотографий (при условии строго увеличивающихся / последовательных идентификаторов) могут быть сгруппированы как event. И несколько событий могут быть сгруппированы как album. Я пытаюсь формализовать это, используя ограничения внешнего ключа.

Но я хочу начать с малого, просто с таблицы photo и заставить это работать :) Мой вопрос: как мне выйти на правая нога с миграциями, как в onUpgrade() et c? Я думаю, что первая миграция идет от базы данных к настройке?

public class MyappDbHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "Myapp.db";

    public MyappDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        //db.execSQL(AlbumContract.SQL_CREATE_ALBUM);  // I'm starting with just the PHOTO and STACK tables
        //db.execSQL(AlbumContract.SQL_CREATE_EVENT);
        db.execSQL(AlbumContract.SQL_CREATE_PHOTO);
        db.execSQL(AlbumContract.SQL_CREATE_STACK);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

1 Ответ

1 голос
/ 21 марта 2020

Кажется, вы пытаетесь использовать старый подход для создания базы данных SQLite. Если вы используете библиотеку Room для работы с SQLite, то вы должны создать классы @Entity и @Dao (объект доступа к данным) для ваших данных и класс @Database, который расширяет RoomDatabase.

Для код вашего дела выглядит следующим образом:

@Entity
public class Photo {

    @PrimaryKey
    public int photoId;

    @ColumnInfo(name = "mediastoreUri")
    public String mediastoreUri;

    @ColumnInfo(name = "description")
    public String description;

    @ColumnInfo(name = "photoEventId")
    public long photoEventId;
}

@Entity
public class Event {

    @PrimaryKey
    public int eventId;

    @ColumnInfo(name = "title")
    public String title;

    @ColumnInfo(name = "subtitle")
    public String subtitle;
}

// One-to-Many relationship
public class EventWithPhotos {

    @Embedded
    public Event event;

    @Relation(
        parentColumn = "eventId",
        entityColumn = "photoEventId"
    )
    public List<Photo> photos;
}

@Dao
public interface PhotoDao {

    @Query("SELECT * FROM Photo")
    List<Photo> getAll();

    @Query("SELECT * FROM Photo WHERE photoId IN (:ids)")
    List<Photo> loadAllByIds(int[] ids);

    @Insert
    void insertAll(Photo... photos);

    @Delete
    void delete(Photo photo);
}

@Database(entities = {Photo.class, Event.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract PhotoDao userDao();
}

Подробнее см .: Обзор комнаты , Отношения в комнате , Миграции в комнате

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...