android - Android - 房间预填充数据库的疑问
问题描述
我必须在第一次运行时预先填充一个 Room 数据库,我看到了 Florina Muntenescu 关于它的要点。
所以,我们有...
@Database(entities = arrayOf(Data::class), version = 1)
abstract class DataDatabase : RoomDatabase() {
abstract fun dataDao(): DataDao
companion object {
@Volatile private var INSTANCE: DataDatabase? = null
fun getInstance(context: Context): DataDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext,
DataDatabase::class.java, "Sample.db")
// prepopulate the database after onCreate was called
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
// insert the data on the IO Thread
ioThread {
getInstance(context).dataDao().insertData(PREPOPULATE_DATA)
}
}
})
.build()
val PREPOPULATE_DATA = listOf(Data("1", "val"), Data("2", "val 2"))
}
但我不明白我应该在哪里调用这个 getInstance 方法,我是否需要在我的片段、MainActivity 或其他地方进行一些虚拟 DAO 调用(只是为了填充 DB)?(假设我打算在这个项目中使用 MVVM)。
或者也许我只是疲倦和盲目地看到解决方案......
解决方案
对我来说,使用 ROOM 创建和访问数据库有 5 个步骤。
1)设置实体,是您的名称对象(数据库中的每个条目)。
@Entity(tableName = "my_table")
public class MyEntity {
@PrimaryKey(autoGenerate = true)
private int mId;
private String mFirstName;
private String mLastName;
public MyEntity(String firstName, String lastName) {
this.mFirstName = firstName;
this.mLastName = lastName;
}
public int getId() {
return mId;
}
public String getFirstName() {
return mFirstName;
}
public String getLastName() {
return mLastName;
}
public void setId(int mId) {
this.mId = mId;
}
}
2)设置DAO,DAO是你与数据库通信的方式。
@Dao
public interface MyDao {
@Query("SELECT * FROM my_table")
LiveData<List<MyEntity>> getAllNames();
@Inster
void insert(MyEntity name);
3) 设置数据库
@DataBase(entities = {MyEntity.class}, version 1, exportschema = false}
public abastract class MyDatabase extends RoomDatabase {
private static MyDatabase INSTANCE;
public MyDao mMyDao;
public static synchronized MyDatabase getInstance(Context context) {
if(INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
MyDatabase.class "database_name")
.fallbackToDestructiveMigration()
.addCallback(roomCallBack)
.build();
}
return INSTANCE;
private static RoomDatabase.Callback roomCallBack = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
new PopulateDbAsyncTask(INSTANCE).execute();
}
};
}
private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
private MyDao mMyDao;
public PopulateDbAsyncTask(MyDatabase db) {
this.mMyDao = db.MyDao();
}
@Override
protected Void doInBackground(Void... voids) {
mMyDao.insert(new MyEntity("FirstName", "LastName")
// Repeat as many times as needed.
return null;
}
}
4)设置存储库,存储库调用/创建数据库
public class MyRepository {
private MyDao mMyDao;
private LiveData<List<MyEntity>> mMyList;
// Constructor will call the database Class.
public MyRepository(Application application) {
MyDatabase db = MyDatabase.getInstance(application);
this.mMyDao = db.mMyDao;
mMyList = mMyDao.getAllNames();
}
public LiveData<List<MyEntity> getAllNames() {
return mMyList;
}
}
5)设置视图模型,从活动或片段访问您的视图模型。
public class MyViewModel extends ViewModel {
private LiveData<List<MyEntity>> mMyList;
private Repository mRepository;
public MyViewModel(Application application) {
this.mApplication = application;
mRepository = new Repository(application);
this.mMyList = mRepository.getAllNames;
}
public LiveData<List<MyEntity>> getAllNames() {
return mMyList = mRepository.getAllNames();
}
推荐阅读
- mysql - 关于mysql别名有什么具体规则吗?
- python - 如何让 Flask 应用程序与 HTML 选项进行交互
- javascript - p5.js 实例模式下的依赖,不传递实例
- html - 填满引导导航栏的整个宽度
- javascript - 你如何替换一个值并在 5 分钟后恢复它的旧值?
- teamcity - Team City 将单元测试结果发布到工件
- python - 使用函数翻译数据帧时出错
- r - R Shiny 使用 textInput() 读取多个数字
- javascript - 如何使用异步等待和对反应流的突变对命令式代码进行建模
- java - 如何使用 SQLite ID 自动增量?