Android-Room预填充数据库

Android-Room预填充数据库,android,android-room,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 I

我必须在第一次运行时预先填充一个房间数据库,我看到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)


或者我只是太累了,瞎了眼,看不到解决方案……

我不能100%确定我是否理解你的最终目标是什么;但是,当我编写使用SQLite数据库的应用程序时,我希望有一些虚拟信息,可以立即添加到数据库中,以便查看我的所有不同活动将如何响应查询等

在我的主屏幕上,我通常会放一个按钮,上面写着“添加虚拟数据”。单击后,它从我的SQLHelper类调用函数addDummyData()来编写大约20条insert语句。一旦我的应用程序启动并按我想要的方式运行,我将在分发之前删除该按钮


如果您添加要自动调用的insert语句(即,无需用户按下按钮、选择菜单项等干预),则您的应用程序可能会在每次启动时添加相同的20行insert语句。您的数据库将很快被多个副本淹没。您需要添加一个if{}语句,首先检查数据库中是否已经存在数据(例如,使用返回游标运行一个查询,查找其中一个伪值,如果游标计数为零,则继续填充数据库,否则不填充),创建和访问带有文件室的数据库有5个步骤

1) 设置实体是您的名称对象(数据库中的每个条目)

2) 设置DAO,DAO是您与数据库通信的方式

@Dao
public interface MyDao {
    @Query("SELECT * FROM my_table")
    LiveData<List<MyEntity>> getAllNames();

    @Inster
     void insert(MyEntity name);

@Dao
公共接口MyDao{
@查询(“从我的表格中选择*)
LiveData getAllNames();
@仪表
无效插入(我的实体名称);
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;
        }
    }
@DataBase(entities={MyEntity.class},版本1,exportschema=false}
公共数据库类MyDatabase扩展了RoomDatabase{
私有静态数据库实例;
公共MyDao-mMyDao;
公共静态同步MyDatabase getInstance(上下文){
if(实例==null){
实例=Room.databaseBuilder(context.getApplicationContext(),
MyDatabase.class“数据库名称”)
.fallbackToDestructiveMigration()
.addCallback(roomCallBack)
.build();
}
返回实例;
私有静态RoomDatabase.Callback roomCallBack=新建RoomDatabase.Callback(){
@凌驾
public void onCreate(@NonNull SupportSQLiteDatabase db){
super.onCreate(db);
新填充的Basynctask(实例).execute();
}
};
}
私有静态类填充Basynctask扩展异步任务{
私家MyDao mMyDao;
公共填充的Basynctask(MyDatabase db){
this.mMyDao=db.MyDao();
}
@凌驾
受保护的空位背景(空位…空位){
插入(新MyEntity(“姓氏”、“姓氏”)
//根据需要重复多次。
返回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;
    }
}
公共类MyRepository{
私家MyDao mMyDao;
私有LiveData-mMyList;
//构造函数将调用数据库类。
公共MyRepository(应用程序){
MyDatabase db=MyDatabase.getInstance(应用程序);
this.mMyDao=db.mMyDao;
mMyList=mMyDao.getAllNames();
}

public livedata当您需要执行DB操作时,必须调用
getInstance
方法。您只需执行
database.getInstance(context.dataDao())
使用dataDao操作。您可以在应用程序的onCreate方法中调用getInstance方法来预填充数据库以进行测试/开发。我明白了。只需简单的调用即可完成所有工作。谢谢。
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;
    }
}
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();
    }