[英]Move data from sqlite database file to room
我有一個處理外部數據庫(sqlite 數據庫文件)的項目,我想移動到房間數據庫,如下所示
這是我項目的一些文件
@Entity(tableName = "books_table")
public class Book {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "book_id")
private long id;
@ColumnInfo(name = "book_name")
private String name;
@ColumnInfo(name = "all")
private long all;
@ColumnInfo(name = "profile_id")
private long profileId;
public Book() {
}
public Book(String name, long all, long profileId) {
this.name = name;
this.all = all;
this.profileId = profileId;
}
@Dao
public interface BookDAO {
@Insert
void insertBook(Book... book);
@Update
void updateBook(Book... book);
@Entity (tableName = "profiles_table")
public class Profile {
@PrimaryKey(autoGenerate = true)
long id;
@ColumnInfo (name = "profile_name")
String profileName;
public Profile() {
}
public Profile(long id, String profileName) {
this.id = id;
this.profileName = profileName;
}
public Profile(String profileName) {
this.profileName = profileName;
}
@Dao
public interface ProfileDAO {
@Insert
void insertProfile(Profile... profile);
@Update
void updateProfile(Profile... profile);
@Database(entities = {Book.class , Profile.class}, version = 1, exportSchema = false)
public abstract class MyRoomDatabase extends RoomDatabase {
public abstract BookDAO bookDao();
public abstract ProfileDAO profileDAO();
private static volatile MyRoomDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
static MyRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (MyRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
MyRoomDatabase.class, "student_prepare_room_database")
.addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
// If you want to keep data through app restarts,
// comment out the following block
databaseWriteExecutor.execute(() -> {
// Populate the database in the background.
// If you want to start with more words, just add them.
});
}
};
}
student_database.db
CREATE TABLE "profile_table" ("id" INTEGER,"profile_name" TEXT,PRIMARY KEY("id"));
[1]: https://i.stack.imgur.com/lDhtR.png
CREATE TABLE "books_table" ("book_id" INTEGER,"book_name" TEXT,"all" INTEGER,"profile_id" INTEGER,PRIMARY KEY("book_id" AUTOINCREMENT));
[2]: https://i.stack.imgur.com/NiuZe.png
通常,這將通過使外部數據庫成為資產(預打包的數據庫)並利用將承擔數據庫副本的.createFromAsset
來實現。
但是,使用上述內容確實需要資產數據庫嚴格符合房間模式,該模式由使用@Entity 注釋的類定義,並包含在通過@Database 注釋提供的實體列表/數組中。
可以使用 prePackagedDatabaseCallback 修改預打包的數據庫以適應。 但是,對外部數據庫進行更改以使其符合房間的預期可能更簡單。
在您的情況下,例如,您的配置文件表中存在不匹配,因為在外部/預打包數據庫中您的id為(有效) INTEGER PRIMARY KEY
而使用@PrimaryKey(autoGenerate = true)
房間期望INTEGER PRIMARY KEY AUTOINCREMENT
。
AUTOINCREMENT
(in room autogenerate = true
) 效率低下且很少需要。 您可以更改為使用@PrimaryKey
。只討論了一個不匹配的例子,因為幾乎沒有必要深入研究所有會導致問題的不匹配。 也就是說,當您編譯項目時,當使用 @Entity 注釋的類已創建並包含在 @Database 注釋中的類列表中時,房間將生成預期的 CREATE TABLE 語句。 因此,您可以根據 room 創建的 SQL 輕松對外部/預打包表進行所需的更改。
The SQL created by Room is found in the java(generated) (visible in the Android View)m, the class to look for is one named the same as the class annotated with @Database but suffixed with _Impl. SQL 在名為createAllTables
的方法中找到。 您不想創建 room_master_table,它是 room 用於存儲模式的 hash 表示形式的表,並用於檢查是否對模式進行了更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.