如何使用房间预填充数据库?我看不到参见教程,该教程使用Java在详细信息中解释

发布于 2025-01-23 10:33:41 字数 325 浏览 0 评论 0 原文

我检查了以下链接: https://developer.android.com/training/data - 存储/房间/预填充 而且我不知道这样做的一步。

我不知道我会在数据库文件中写些什么,我仍然需要一些示例。 我不知道如何访问预处理的数据库,例如我将使用哪些功能/方法。我真的不知道。请帮忙。

大多数教程在Kotlin完成。

I checked this link: https://developer.android.com/training/data-storage/room/prepopulate
and I don't know the step by step of doing it.

I don't know what will I write in the db file, I still need some examples.
I don't know how to access the prepopulated db, like what functions/methods will I use. I really have no idea. Please help.

Most tutorials are done in kotlin.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

话少情深 2025-01-30 10:33:41

您可能希望考虑以下内容,即使它似乎是错误的订单(它可能会克服可怕的期望/发现的问题的困惑问题,这些问题通常与试图适应房间的实体来满足现有数据库有关),

  • 如果您已经有一个填充的预包装数据库,您可能会发现添加步骤更容易创建房间预期的表,从现有表中复制数据并之后将它们放下(与试图确定房间的细微差别相比,可能更令人困惑)。
  1. 设计并为数据库创建模式。
  2. 使用架构创建房间的实体,这是每张表@Entity注释的类。
  3. 创建一个适当的 @database 带注释的抽象类,该类包括 entities = @code> @database entotation的所有@entity注释类。
  4. 编译(成功)项目。
  5. 在Android Studio的Android视图中,请查看生成的Java,将有一个类别的名称与 @database 注释的类相同,但带有 _IMPL 的后缀。在此类中,将有一种称为 createLtables 的方法,您将看到每个表和任何补充索引的 execsql 语句
    • 注意,如果您使用视图,则需要创建 @view 注释的类并遵循类似的过程。但是,视图并不常见,因此尚未包括在内。
  6. 使用 execsq l语句中的SQL 在喜欢的SQL工具中创建您的表(例如SQLITE,NAVICAT,DBEAVER)。
  7. 使用SQLite工具填充数据库。
  8. 关闭并保存数据库(建议您打开数据库,然后检查是否如预期,然后关闭并再次保存数据库(某些工具有时不关闭数据库))
  9. 在项目中创建资产文件夹。
  10. 将保存的数据库文件复制到资产文件夹中。
  11. 添加/修改房间的构建方法,以 .createfromasset(“ the_database_file_name_including_extension_if_if_one”)>
    • 这告诉房间,当构建数据库时,如果数据库不存在,则从资产文件夹复制数据库。
  12. 保存和编译,然后进行应用。

遵循上述顺序,尤其是使用空间生成SQL,将规避在列类型亲和力和列约束方面的房间的细微差别。

  • 例如,您不能具有不具有整数,文本,真实或斑点的列类型。

这是一个名为table1的单个表的示例,该表具有6列

table1 @entity注释类: -

@Entity /*(
        primaryKeys = {"column_name","more_columns_for_a_composite_primary"},
        tableName = "alternative_table_name"
)*/
class Table1 {
    /* in ROOM every table MUST have a column either annotated with @PrimaryKey
        or have a primary key specified in the primaryKeys parameter of the @Entity annotation
     */
    @PrimaryKey
    Long id = null; /* this will be a typically id column that will, if no value is specified, be generated (must be Long not long) */
    String text_column;
    @NonNull
    String notnull_text_column;
    double real_column;
    byte[] blob_column;
    @NonNull
    @ColumnInfo(index = true)
    double notnull_real_column_also_indexed;

}

@database注释的类, thedatabase ,包括Singleton获得实例。

@Database(entities = {Table1.class}, version = 1, exportSchema = false)
abstract class TheDatabase extends RoomDatabase {

   private volatile static TheDatabase instance = null;

   public static TheDatabase getInstance(Context context) {
      if (instance == null) {
         instance = Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
                 .allowMainThreadQueries() /* for convenience and brevity */
                 .createFromAsset("the_database.db")
                 .build();
      }
      return instance;
   }
}

使用以上内容,可以编译该项目(CTRL+F9),然后与@database注释类关联的生成的Java可以位于EG

“在此处输入图像描述”

在类中,会有一个方法名称createAltables: -

@SuppressWarnings({"unchecked", "deprecation"})
public final class TheDatabase_Impl extends TheDatabase {
  @Override
  protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
    final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate(1) {
      @Override
      public void createAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("CREATE TABLE IF NOT EXISTS `Table1` (`id` INTEGER, `text_column` TEXT, `notnull_text_column` TEXT NOT NULL, `real_column` REAL NOT NULL, `blob_column` BLOB, `notnull_real_column_also_indexed` REAL NOT NULL, PRIMARY KEY(`id`))");
        _db.execSQL("CREATE INDEX IF NOT EXISTS `index_Table1_notnull_real_column_also_indexed` ON `Table1` (`notnull_real_column_also_indexed`)");
        _db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
        _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a6ca75e8ee6037ad13c258cdc0405ef1')");
      }

      @Override
      public void dropAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("DROP TABLE IF EXISTS `Table1`");
        if (mCallbacks != null) {
          for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
            mCallbacks.get(_i).onDestructiveMigration(_db);
          }
        }
      }
      ....

可以看出,Table1表有一个 execsq l,另一个用于索引(as index = true true是在 @ColumnInfo 注释中指定的)。

  • 房间使用Room_master_table来存储模式,这是不需要的,不应在将复制到资产文件夹中的预包装数据库中创建。

    • 如果架构更改( @entity注释类),哈希将会更改
  • 细微差别

    • 如果您仔细观察,您会发现real_column和notnull_real_column都具有非零约束,但只有后者具有 @nonnull 注释。这是因为double是一个原始的,并且始终具有一个值,因此房间隐含地应用了不是无效的约束。如果在创建预包装数据库时未编码非零约束,则在复制资产后,运行应用程序时,将发生一个例外,因为发现的数据库(从资产复制的数据库)将是不同的(从房间看来),从房间的期望(根据@Entity注释的分类中定义的架构中的架构中定义在@database注释中的实体列表中定义)。 因此,为什么建议它通过房间创建模式,提取生成的SQL并使用它来创建预包装的数据库。这样可以确保数据库模式如预期的。
    • 请注意,这只是一个细微差别的示例

继续使用一个有效的示例

一件事,通常会绊倒Sqlite的新用户,并且还有空间是,当您实例化数据库类时,那就不会创建或打开数据库。直到试图访问数据库(从数据库中更改或提取数据),并且在必要时开放数据库,并且在必要的情况下以及在资产中复制的预先填充的数据库(或文件)(或文件)以前的)。

因此,在准备中,为此A(可以是一个或多个),创建了用 @dao 注释的接口或抽象类。在这种情况下, alldao 按照: -

@Dao
abstract class AllDAO {
    @Insert
    abstract long insert(Table1 table1);
    @Query("SELECT * FROM table1")
    abstract List<Table1> getAllTable1s();
}
  • 使用 insert getalltable1s 将访问数据库。

@dao 注释的类(ES)必须在房间中知道/定义,通常@database类包括此信息,因此 thedatabase 类可以是

@Database(entities = {Table1.class}, version = 1, exportSchema = false)
abstract class TheDatabase extends RoomDatabase {
   abstract AllDAO getAllDAO(); //<<<<< ADDED to allow use of the database
   private volatile static TheDatabase instance = null;

   public static TheDatabase getInstance(Context context) {
      if (instance == null) {
         instance = Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
                 .allowMainThreadQueries() /* for convenience and brevity */
                 .createFromAsset("the_database.db")
                 .build();
      }
      return instance;
   }
}

:实际上准备就绪(在活动中使用它将在稍后进行处理)。

现在,预包装的数据库可以使用SQLITE工具(在这种情况下已使用sqlite的Navicat)进行验证/构建,这无关紧要)。

建立并打开了连接,此详细信息将存储数据库文件。 (如果需要,请参见工具的帮助)。在这种情况下,数据库被命名为 soquestions (已经存在): -

“在此处输入图像说明”

单击新查询,并粘贴了用户定义的表格的SQL,以及索引。例如: -

因此,表格和索引现在存在,但没有被人群。因此,现在通过插入一些记录来填充数据库。将使用查询(在这种情况下,因为这只是一个示例,因此如果需要查询,则可以保存)。

因此,将现有的SQL删除并替换为(并非删除所有行,因此可重新纳入),然后运行: -

“ noreferrer”> “在此处输入图像说明”

是: -

​。建议关闭数据库/连接,然后重新打开以检查数据是否已保存,然后最终再次关闭(这是完成的)。

该数据库现在准备被复制到资产文件夹中(目前不存在)。因此,在项目中创建资产文件夹(返回Android Studio)。文件/目录用于选择src \ main \ Assets: -

”在此处输入映像说明“

获取: -

“在此处输入图像说明”

从Windows Explorer中复制文件(右键单击文件,然后复制)<)

< a href =“ https://i.sstatic.net/yvcob.png” rel =“ noreferrer”>

并粘贴(右键单击Andriod Studio和paste中的资产文件夹),将其重命名为the_database.db(根据 create> createfromasset (可以使用)(数据库名称)(可以使用 soquestions.db 作为资产文件名)

“在此处输入图像说明”

在: -

“在此处输入image

现在通过在一个中使用数据库来运行该应用程序活动(请注意,为了简单和便利,这是在主线程上运行的)。

活动代码: -

public class MainActivity extends AppCompatActivity {

    TheDatabase dbInstance;
    AllDAO dao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbInstance = TheDatabase.getInstance(this); /* get DB Instance */
        dao = dbInstance.getAllDAO(); /* get the appropriate Dao */
        logAllRowsFromTable1("PRENEWDATA"); /* WILL INITIATE THE ASSET COPY (if DB does not exist) */
        Table1 newTable1Row = new Table1();
        newTable1Row.text_column = "a new row";
        newTable1Row.blob_column = new byte[30];
        newTable1Row.notnull_text_column = " the new nottnull_text_column";
        newTable1Row.real_column = 4444.55555;
        newTable1Row.notnull_real_column_also_indexed = 7777.8888;
        dao.insert(newTable1Row); /* IF NOT INITIATED ABOVE WILL INITIATE THE ASSET COPY (if DB does not exist)*/
        logAllRowsFromTable1("POSTNEWDATA");
    }

    void logAllRowsFromTable1(String suffix) {
        for (Table1 t: dao.getAllTable1s()) {
            Log.d("DB-" + suffix,
                    "ID is " + t.real_column
                    + "\n\tTEXT_COLUMN is " + t.text_column
                    + "\n\t NOTNULL_TEXT_COLUMN is " + t.notnull_text_column
                    + "\n\t REAL_COLUMN is " + t.real_column
                    + "\n\t NOTNULL_REAL_COLUMN... is " + t.notnull_real_column_also_indexed
                    /* not doing the blob so as not to complicate matters */
            );
        }
    }

这将首先输出所有行,从预包装数据库到日志。
然后,它将添加一个新运行(每次运行,只是一个演示/示例),然后从更新的(新行)数据库中输出所有行的某些数据。

例如: -

2022-04-22 11:00:43.689 D/DB-PRENEWDATA: ID is 10.3333
        TEXT_COLUMN is some text
         NOTNULL_TEXT_COLUMN is some notnull text
         REAL_COLUMN is 10.3333
         NOTNULL_REAL_COLUMN... is 3.1
2022-04-22 11:00:43.689 D/DB-PRENEWDATA: ID is 11.3333
        TEXT_COLUMN is null
         NOTNULL_TEXT_COLUMN is more not null text
         REAL_COLUMN is 11.3333
         NOTNULL_REAL_COLUMN... is 4.1
         
         
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 10.3333
        TEXT_COLUMN is some text
         NOTNULL_TEXT_COLUMN is some notnull text
         REAL_COLUMN is 10.3333
         NOTNULL_REAL_COLUMN... is 3.1
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 11.3333
        TEXT_COLUMN is null
         NOTNULL_TEXT_COLUMN is more not null text
         REAL_COLUMN is 11.3333
         NOTNULL_REAL_COLUMN... is 4.1
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 4444.55555
        TEXT_COLUMN is a new row
         NOTNULL_TEXT_COLUMN is  the new nottnull_text_column
         REAL_COLUMN is 4444.55555
         NOTNULL_REAL_COLUMN... is 7777.8888
  • 添加的空白行以区分两组Output

Android Studio的应用程序检查可用于查看实际数据: -

”

You may wish to consider the following, even though it may appear to be the wrong order (it may overcome perplexing issues with the dreaded Expected/Found issue that is often associated with trying to adapt room's entities to cater for an existing database)

  • If you already have a populated pre-packaged database you may find it easier to add steps to create the Room expected tables, copy the data from the existing tables and drop them afterwards (still probably less perplexing than trying to ascertain the nuances of Room).
  1. Design and create your schema for the database.
  2. Using the schema create the entities for Room, that is a class annotated with @Entity per table.
  3. Create an appropriate @Database annotated abstract class that includes ALL of the @Entity annotated class in the entities = parameter of the @Database annotation.
  4. Compile (successfully) the project.
  5. In the Android View of Android Studio look at the generated java there will be a class that has the same names as the @Database annotated class but suffixed with _Impl. In this class there will be a method called createAllTables and you will see an execSQL statement for each table and any supplementary indexes
    • note if you use Views then you need to create the @View annotated classes and follow the similar procedure. However, Views are not common though and hence they have not been included.
  6. Use the SQL from the execSQL statements to create your tables in favourite SQL tool (e.g. DB Browser for SQLite, Navicat, DBeaver).
  7. Populate the database using your SQLite Tool.
  8. Close and Save the database (it is suggested that you then Open the database and check that it is as expected and then Close and Save the database again (some tools sometimes don't close the database))
  9. Create the assets folder in your project.
  10. Copy the saved database file into the assets folder.
  11. add/amend where you undertake the Room's build method, to precede it with .createFromAsset("the_database_file_name_including_extension_if_one")
    • this tells Room, when building the database, if the database does not exist, to copy the database from the assets folder.
  12. Save and compile and then the App.

Following the above order, especially using Room to generate the SQL, will circumvent having to understand the nuances of Room in regards to column type affinities and column constraints.

  • for example you CANNOT have a column type that is not INTEGER, TEXT, REAL or BLOB.

Here's an example with a single table named Table1 that has 6 columns

The Table1 @Entity annotated class :-

@Entity /*(
        primaryKeys = {"column_name","more_columns_for_a_composite_primary"},
        tableName = "alternative_table_name"
)*/
class Table1 {
    /* in ROOM every table MUST have a column either annotated with @PrimaryKey
        or have a primary key specified in the primaryKeys parameter of the @Entity annotation
     */
    @PrimaryKey
    Long id = null; /* this will be a typically id column that will, if no value is specified, be generated (must be Long not long) */
    String text_column;
    @NonNull
    String notnull_text_column;
    double real_column;
    byte[] blob_column;
    @NonNull
    @ColumnInfo(index = true)
    double notnull_real_column_also_indexed;

}

The @Database annotated class, TheDatabase,including singleton for getting an instance.

@Database(entities = {Table1.class}, version = 1, exportSchema = false)
abstract class TheDatabase extends RoomDatabase {

   private volatile static TheDatabase instance = null;

   public static TheDatabase getInstance(Context context) {
      if (instance == null) {
         instance = Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
                 .allowMainThreadQueries() /* for convenience and brevity */
                 .createFromAsset("the_database.db")
                 .build();
      }
      return instance;
   }
}

With the above, the project can be compiled (Ctrl+F9), and then the generated java associated with the @Database annotated class can be located e.g.

enter image description here

Within the class there will be a method name createAllTables :-

@SuppressWarnings({"unchecked", "deprecation"})
public final class TheDatabase_Impl extends TheDatabase {
  @Override
  protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
    final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate(1) {
      @Override
      public void createAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("CREATE TABLE IF NOT EXISTS `Table1` (`id` INTEGER, `text_column` TEXT, `notnull_text_column` TEXT NOT NULL, `real_column` REAL NOT NULL, `blob_column` BLOB, `notnull_real_column_also_indexed` REAL NOT NULL, PRIMARY KEY(`id`))");
        _db.execSQL("CREATE INDEX IF NOT EXISTS `index_Table1_notnull_real_column_also_indexed` ON `Table1` (`notnull_real_column_also_indexed`)");
        _db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
        _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a6ca75e8ee6037ad13c258cdc0405ef1')");
      }

      @Override
      public void dropAllTables(SupportSQLiteDatabase _db) {
        _db.execSQL("DROP TABLE IF EXISTS `Table1`");
        if (mCallbacks != null) {
          for (int _i = 0, _size = mCallbacks.size(); _i < _size; _i++) {
            mCallbacks.get(_i).onDestructiveMigration(_db);
          }
        }
      }
      ....

As can be seen there is an execSQL for the table1 table, another for the index (as index = true was specified in the @ColumnInfo annotation).

  • the room_master_table is used by room to store a hash of the schema, this is not needed, and should NOT be created in the pre-packaged database that will be copied into the assets folder.

    • The hash will change if the schema changes (the @Entity annotated classes)
  • Nuances

    • if you look closely, you will see that both the real_column and the notnull_real_column have the NOT NULL constraint, but only the latter has the @NonNull annotation. This is because double, is a primitive and ALWAYS has a value, so Room implicitly applies the NOT NULL constraint. If the NOT NULL constraint is not coded when creating the pre-packaged database then after the asset has been copied, when running the App, an exception will occur as the database that was found (the one copied from the asset) will be different (in Room's view) from what Room expected (the schema according to the @Entity annotated classed defined in the list of entities in the @Database annotation). Hence, why it is suggested to create the schema via room, extract the generated SQL and use this to create the pre-packaged database. This ensures that the database schema is as expected.
    • Note this is just one example of the nuances

Continuing with a working example

One thing that often trips new users of SQLite and also Room is that when you instantiate the Database class, is that, it does not then create or open the database. It is not until an attempt is made to access the database (changing or extracting data from the database) that the database is opened and if necessary created and in the case of a pre-populated database copied from the asset (or file, normally the former).

As such, in preparation, for this a (can be one or more), an interface or abstract class annotated with @Dao is created. In this case AllDAO as per:-

@Dao
abstract class AllDAO {
    @Insert
    abstract long insert(Table1 table1);
    @Query("SELECT * FROM table1")
    abstract List<Table1> getAllTable1s();
}
  • using either the insert or the getAllTable1s would access the database.

The @Dao annotated class(es) have to be known/defined to Room, typically the @Database class includes this so the TheDatabase class could then be:-

@Database(entities = {Table1.class}, version = 1, exportSchema = false)
abstract class TheDatabase extends RoomDatabase {
   abstract AllDAO getAllDAO(); //<<<<< ADDED to allow use of the database
   private volatile static TheDatabase instance = null;

   public static TheDatabase getInstance(Context context) {
      if (instance == null) {
         instance = Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
                 .allowMainThreadQueries() /* for convenience and brevity */
                 .createFromAsset("the_database.db")
                 .build();
      }
      return instance;
   }
}

So the App is virtually ready (using it in an activity will be dealt with later).

Now the pre-packaged database can be perpared/built using an SQLite tool (Navicat for SQLite has been used in this case, it shouldn't matter which).

A connection is made and opened, this detailing where the database file will be stored. (see the tool's help if needed). In this case the database is named SOQuestions (already exists) :-

enter image description here

New Query is clicked, and the SQL for the user defined tables is pasted, as well as the indexes. e.g.:-

enter image description here

So the table(s) and indexes now exist but are unpopulated. So now to populate the database by inserting some records. A query will be used (in this case as it's only an example queries won't be saved, they could if desired).

So the existing SQL is deleted and replaced with (not deletes all rows, so it is rerunnable) and then run:-

enter image description here

The resultant data being :-

enter image description here

The database should be saved. It is suggested that the database/connection is closed and then reopened to check that the data has been saved and then finally closed again (this was done).

The database is now ready to be copied into the assets folder (which currently doesn't exist). So create the assets folder in the project (back to Android Studio). File/Directory was used to select src\main\assets :-

enter image description here

to get :-

enter image description here

The file is copied, from Windows Explorer (right click on the file and copy)

enter image description here

and pasted (right click on the assets folder in Andriod Studio and Paste), renaming it to the_database.db (the database name, as per the createFromAsset (could use soquestions.db as the asset file name))

enter image description here

resulting in :-

enter image description here

Now to running the App by using the database in an activity (note that for brevity and convenience this is run on the main thread).

The activity code :-

public class MainActivity extends AppCompatActivity {

    TheDatabase dbInstance;
    AllDAO dao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbInstance = TheDatabase.getInstance(this); /* get DB Instance */
        dao = dbInstance.getAllDAO(); /* get the appropriate Dao */
        logAllRowsFromTable1("PRENEWDATA"); /* WILL INITIATE THE ASSET COPY (if DB does not exist) */
        Table1 newTable1Row = new Table1();
        newTable1Row.text_column = "a new row";
        newTable1Row.blob_column = new byte[30];
        newTable1Row.notnull_text_column = " the new nottnull_text_column";
        newTable1Row.real_column = 4444.55555;
        newTable1Row.notnull_real_column_also_indexed = 7777.8888;
        dao.insert(newTable1Row); /* IF NOT INITIATED ABOVE WILL INITIATE THE ASSET COPY (if DB does not exist)*/
        logAllRowsFromTable1("POSTNEWDATA");
    }

    void logAllRowsFromTable1(String suffix) {
        for (Table1 t: dao.getAllTable1s()) {
            Log.d("DB-" + suffix,
                    "ID is " + t.real_column
                    + "\n\tTEXT_COLUMN is " + t.text_column
                    + "\n\t NOTNULL_TEXT_COLUMN is " + t.notnull_text_column
                    + "\n\t REAL_COLUMN is " + t.real_column
                    + "\n\t NOTNULL_REAL_COLUMN... is " + t.notnull_real_column_also_indexed
                    /* not doing the blob so as not to complicate matters */
            );
        }
    }

This will first output some of the data, for all rows, from the pre-packaged database to the log.
It will then add a new run (each run, it is only a demo/example) and then output some of the data for all rows, from the updated (new row) database.

e.g. :-

2022-04-22 11:00:43.689 D/DB-PRENEWDATA: ID is 10.3333
        TEXT_COLUMN is some text
         NOTNULL_TEXT_COLUMN is some notnull text
         REAL_COLUMN is 10.3333
         NOTNULL_REAL_COLUMN... is 3.1
2022-04-22 11:00:43.689 D/DB-PRENEWDATA: ID is 11.3333
        TEXT_COLUMN is null
         NOTNULL_TEXT_COLUMN is more not null text
         REAL_COLUMN is 11.3333
         NOTNULL_REAL_COLUMN... is 4.1
         
         
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 10.3333
        TEXT_COLUMN is some text
         NOTNULL_TEXT_COLUMN is some notnull text
         REAL_COLUMN is 10.3333
         NOTNULL_REAL_COLUMN... is 3.1
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 11.3333
        TEXT_COLUMN is null
         NOTNULL_TEXT_COLUMN is more not null text
         REAL_COLUMN is 11.3333
         NOTNULL_REAL_COLUMN... is 4.1
2022-04-22 11:00:43.692 D/DB-POSTNEWDATA: ID is 4444.55555
        TEXT_COLUMN is a new row
         NOTNULL_TEXT_COLUMN is  the new nottnull_text_column
         REAL_COLUMN is 4444.55555
         NOTNULL_REAL_COLUMN... is 7777.8888
  • blank lines added to distinguish between the two sets of output

Android Studio's App Inspection can be used to see the actual data:-

enter image description here

爱的十字路口 2025-01-30 10:33:41

您可以使用其他工具(例如“ sqlite for sqlite”)创建数据库,在那里您可以创建表并填充数据,并将数据库另存为.db文件,您将能够将其移至Android Project。

you can create a database using other tools like "db browser for SQLite", there you will be able to create tables and fill them with data and save the database as .db file, which you will be able to move to your android project.

陪我终i 2025-01-30 10:33:41

借助新房间版本,您现在也可以访问RoomDatabase.callbacks()内的数据库,因此最简单的方法是只在数据库构建器中注册一个onCreate回调并执行SQL语句。例如:

Room.databaseBuilder(
  context = appContext,
  klass = MyDatabase::class.java,
  name = "my_database"
).addCallback(object : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        db.execSQL("INSERT INTO my_table (id, value) VALUES (1, 'hello')")
    }
}).build()

对于一些简单的插入语句,这应该足够了,但是,如果您有很多数据要预先填充,则可能不合适。替代方案是从DB文件创建DB(就像Miket在此处描述: https://stackover.com/a/a/a/a/71960555/ 1264616

With the new room versions you can now also access the database inside the RoomDatabase.Callbacks(), so the easiest way would be to just register an onCreate callback in the database builder and execute a SQL statement. E.g.:

Room.databaseBuilder(
  context = appContext,
  klass = MyDatabase::class.java,
  name = "my_database"
).addCallback(object : RoomDatabase.Callback() {
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        db.execSQL("INSERT INTO my_table (id, value) VALUES (1, 'hello')")
    }
}).build()

For some simple insert statements, this should be sufficient, however if you have a lot of data to be pre-populated, this might not be suitable. Alternative would be to create you DB from a DB file (like MikeT already described here: https://stackoverflow.com/a/71960555/1264616)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文