Pokój ma nie mieć dobry system migracji, przynajmniej nie do czasu 2.1.0-alpha03
.
Tak więc, dopóki nie będziemy mieć lepszego systemu migracji, istnieją pewne obejścia umożliwiające łatwe migracje w pokoju.
Ponieważ nie ma takiej metody jak @Database(createNewTables = true)
lub MigrationSystem.createTable(User::class)
, która powinna być taka czy inna, jedyną możliwą drogą jest bieganie
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
wewnątrz twojej migrate
metody.
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
}
}
Aby uzyskać powyższy skrypt SQL , masz 4 sposoby
1. Napisz sam
Zasadniczo musisz napisać powyższy skrypt, który będzie pasował do skryptu generowanego przez Room. Ten sposób jest możliwy, niewykonalny. (Weź pod uwagę, że masz 50 pól)
2. Schemat eksportu
Jeśli umieścisz exportSchema = true
wewnątrz @Database
adnotacji, Room wygeneruje schemat bazy danych w / schemas folderu projektu. Użycie jest
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
}
Upewnij się, że w build.grade
module aplikacji uwzględniono poniższe wiersze
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
Kiedy uruchomisz lub zbudujesz projekt, otrzymasz plik JSON 2.json
, który zawiera wszystkie zapytania w Twojej bazie danych Room.
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "325bd539353db508c5248423a1c88c03",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
Możesz więc uwzględnić powyższe createSql
w swojej migrate
metodzie.
3. Uzyskaj zapytanie z AppDatabase_Impl
Jeśli nie chcesz eksportować schematu, nadal możesz uzyskać zapytanie, uruchamiając lub budując projekt, który wygeneruje AppDatabase_Impl.java
plik. i w określonym pliku, który możesz mieć.
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
W ramach createAllTables
metody zostaną utworzone skrypty wszystkich podmiotów. Możesz to zdobyć i uwzględnić w swojej migrate
metodzie.
4. Przetwarzanie adnotacji.
Jak można się domyślać, Pokój generuje wszystkie wyżej wymienione schema
, a AppDatabase_Impl
pliki w czasie kompilacji oraz z dopiskiem przetworzeniu, które dodasz z
kapt "androidx.room:room-compiler:$room_version"
Oznacza to, że możesz również zrobić to samo i stworzyć własną bibliotekę przetwarzania adnotacji, która generuje wszystkie niezbędne zapytania tworzenia.
Chodzi o to, aby utworzyć bibliotekę przetwarzania adnotacji dla adnotacji pokojów @Entity
i @Database
. Weźmy na przykład zajęcia oznaczone adnotacją @Entity
. Oto kroki, które będziesz musiał wykonać
- Utwórz nowy
StringBuilder
i dołącz „UTWÓRZ TABELĘ, JEŚLI NIE ISTNIEJE”
- Uzyskaj nazwę tabeli z
class.simplename
lub według tableName
pola @Entity
. Dodaj to do swojegoStringBuilder
- Następnie dla każdego pola Twojej klasy utwórz kolumny SQL. Weź nazwę, typ, dopuszczalność wartości null pola według samego pola lub
@ColumnInfo
adnotacji. Dla każdego pola musisz dodać id INTEGER NOT NULL
styl kolumny do swojego StringBuilder
.
- Dodaj klucze podstawowe według
@PrimaryKey
- Dodaj
ForeignKey
i Indices
jeśli istnieje.
- Po zakończeniu zamień go na łańcuch i zapisz w nowej klasie, której chcesz użyć. Na przykład zapisz to jak poniżej
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
Następnie możesz go użyć jako
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
Zrobiłem dla siebie taką bibliotekę, którą możesz sprawdzić, a nawet wykorzystać w swoim projekcie. Zwróć uwagę, że biblioteka, którą utworzyłem, nie jest pełna i po prostu spełnia moje wymagania dotyczące tworzenia tabel.
RoomExtension dla lepszej migracji
Aplikacja korzystająca z RoomExtension
Mam nadzieję, że to było przydatne.
AKTUALIZACJA
W chwili pisania tej odpowiedzi wersja pokoju była 2.1.0-alpha03
i kiedy wysłałem e-mail do programistów, otrzymałem odpowiedź
Oczekuje się, że będzie miał lepszy system migracji w 2.2.0
Niestety wciąż brakuje nam lepszego systemu migracji.