如何使用房间预填充数据库?我看不到参见教程,该教程使用Java在详细信息中解释
我检查了以下链接: https://developer.android.com/training/data - 存储/房间/预填充 而且我不知道这样做的一步。
我不知道我会在数据库文件中写些什么,我仍然需要一些示例。 我不知道如何访问预处理的数据库,例如我将使用哪些功能/方法。我真的不知道。请帮忙。
大多数教程在Kotlin完成。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能希望考虑以下内容,即使它似乎是错误的订单(它可能会克服可怕的期望/发现的问题的困惑问题,这些问题通常与试图适应房间的实体来满足现有数据库有关),
@database
带注释的抽象类,该类包括entities =
@code> @database entotation的所有@entity注释类。@database
注释的类相同,但带有 _IMPL 的后缀。在此类中,将有一种称为 createLtables 的方法,您将看到每个表和任何补充索引的execsql
语句@view
注释的类并遵循类似的过程。但是,视图并不常见,因此尚未包括在内。execsq
l语句中的SQL 在喜欢的SQL工具中创建您的表(例如SQLITE,NAVICAT,DBEAVER)。.createfromasset(“ the_database_file_name_including_extension_if_if_one”)
>遵循上述顺序,尤其是使用空间生成SQL,将规避在列类型亲和力和列约束方面的房间的细微差别。
这是一个名为table1的单个表的示例,该表具有6列
table1 @entity注释类: -
@database注释的类, thedatabase ,包括Singleton获得实例。
使用以上内容,可以编译该项目(CTRL+F9),然后与@database注释类关联的生成的Java可以位于EG
在类中,会有一个方法名称createAltables: -
可以看出,Table1表有一个
execsq
l,另一个用于索引(as index = true true是在@ColumnInfo
注释中指定的)。房间使用Room_master_table来存储模式,这是不需要的,不应在将复制到资产文件夹中的预包装数据库中创建。
细微差别
@nonnull
注释。这是因为double是一个原始的,并且始终具有一个值,因此房间隐含地应用了不是无效的约束。如果在创建预包装数据库时未编码非零约束,则在复制资产后,运行应用程序时,将发生一个例外,因为发现的数据库(从资产复制的数据库)将是不同的(从房间看来),从房间的期望(根据@Entity注释的分类中定义的架构中的架构中定义在@database注释中的实体列表中定义)。 因此,为什么建议它通过房间创建模式,提取生成的SQL并使用它来创建预包装的数据库。这样可以确保数据库模式如预期的。继续使用一个有效的示例
一件事,通常会绊倒Sqlite的新用户,并且还有空间是,当您实例化数据库类时,那就不会创建或打开数据库。直到试图访问数据库(从数据库中更改或提取数据),并且在必要时开放数据库,并且在必要的情况下以及在资产中复制的预先填充的数据库(或文件)(或文件)以前的)。
因此,在准备中,为此A(可以是一个或多个),创建了用
@dao
注释的接口或抽象类。在这种情况下, alldao 按照: -insert
或getalltable1s
将访问数据库。@dao
注释的类(ES)必须在房间中知道/定义,通常@database类包括此信息,因此 thedatabase 类可以是:实际上准备就绪(在活动中使用它将在稍后进行处理)。
现在,预包装的数据库可以使用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 作为资产文件名))在: -
现在通过在一个中使用数据库来运行该应用程序活动(请注意,为了简单和便利,这是在主线程上运行的)。
活动代码: -
这将首先输出所有行,从预包装数据库到日志。
然后,它将添加一个新运行(每次运行,只是一个演示/示例),然后从更新的(新行)数据库中输出所有行的某些数据。
例如: -
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)
@Database
annotated abstract class that includes ALL of the @Entity annotated class in theentities =
parameter of the@Database
annotation.@Database
annotated class but suffixed with _Impl. In this class there will be a method called createAllTables and you will see anexecSQL
statement for each table and any supplementary indexes@View
annotated classes and follow the similar procedure. However, Views are not common though and hence they have not been included.execSQ
L statements to create your tables in favourite SQL tool (e.g. DB Browser for SQLite, Navicat, DBeaver)..createFromAsset("the_database_file_name_including_extension_if_one")
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.
Here's an example with a single table named Table1 that has 6 columns
The Table1 @Entity annotated class :-
The @Database annotated class, TheDatabase,including singleton for getting an 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.
Within the class there will be a method name createAllTables :-
As can be seen there is an
execSQ
L 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.
Nuances
@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.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:-insert
or thegetAllTable1s
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:-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) :-New Query is clicked, and the SQL for the user defined tables is pasted, as well as the indexes. e.g.:-
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:-
The resultant data being :-
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 :-
to get :-
The file is copied, from Windows Explorer (right click on the file and copy)
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))resulting in :-
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 :-
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. :-
Android Studio's App Inspection can be used to see the actual data:-
您可以使用其他工具(例如“ 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.
借助新房间版本,您现在也可以访问RoomDatabase.callbacks()内的数据库,因此最简单的方法是只在数据库构建器中注册一个onCreate回调并执行SQL语句。例如:
对于一些简单的插入语句,这应该足够了,但是,如果您有很多数据要预先填充,则可能不合适。替代方案是从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.:
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)