Android:使用 room 创建的 SQLite 数据库在使用 sqlite-browser 打开时不显示任何表
Android: SQLite database created with room shows no tables when opening with sqlte-browser
我正在使用 Room Persistence Library 1.1.0。我可以使用 Android Studio 的设备文件资源管理器在 /data/data/<package_name>/databases/
找到数据库文件。
它包含多个 tables,我可以使用 room-DAO
s 毫无问题地访问 tables 的内容。然而,当用 sqlite-browser
打开时,显示没有 table.
可能是什么原因?是否可以在不从房间切换回旧 SQLiteOpenHelper
的情况下解决问题?
解决方案
要用sqlite-browser
打开这样的数据库*,你需要复制所有三个文件。所有都必须在同一目录中。
* 如问题所述,数据库存储在多个文件中。
为什么是三个文件?
根据文档,从版本 1.1.0
开始,Room 使用 write-ahead logging
作为具有足够 RAM 的设备的默认日志模式,并在 API 级别 16 上使用 运行 或更高。在这个版本之前,所有设备都是 Truncate
。 write-ahead logging
与 Truncate
相比具有不同的内部结构。
偶尔看看 SQLite
使用的临时文件 :
直到版本 1.1.0
自版本 1.1.0
如果您想将日志模式明确更改为Truncate
,您可以这样做。但是,不推荐因为WAL
比Truncate
好很多。
public static void initialize(Context context) {
sAppDatabase = Room.databaseBuilder(
context,
AppDatabase.class,
DATABASE_NAME)
.setJournalMode(JournalMode.TRUNCATE).build();
}
是否可以在不更改为 Truncate
的情况下将其移动到单个文件?
是的,是的。针对数据库查询以下语句。
pragma wal_checkpoint(full)
此处详细讨论。
您可以使用 wal_checkpoint
pragma 来触发 checkpoint,这会将 WAL 文件事务移回数据库。
theRoomDb.query("pragma wal_checkpoint(full)", null)
或
// the result
// contains 1 row with 3 columns
// busy, log, checkpointed
Cursor cursor = theRoomDb.query("pragma wal_checkpoint(full)", null)
有关 pragma 参数值和结果的更多详细信息,请参阅 PRAGMA Statements。
如果 WAL 未启用,则 pragma 不执行任何操作。
对了,我是用Room 1.1.1测试的,默认没有使用WAL模式,只好开启了。
将 AndroidStudio 中设备文件资源管理器中的所有三个文件复制到您的 PC 目录,并在 SQLite 数据库浏览器中打开 db 文件 (http://sqlitebrowser.org)。确保所有三个文件都在同一个文件夹中。
房间数据库导出和导入解决方案
我在我的一个项目中遇到了同样的问题,我花了两天时间来解决这个问题。
解决方案
Don't create multiple instance for Room library. Multiple instance creating all the problems.
我的应用程序
class MyApplication: Application()
{
companion object {
lateinit var mInstanceDB: AppDatabase
}
override fun onCreate() {
super.onCreate()
mInstanceDB = AppDatabase.getInstance(this)
}
}
AppDatabase
fun getInstance(context: Context): AppDatabase
{
if (sInstance == null) {
sInstance = Room.databaseBuilder(context.applicationContext,AppDatabase::class.java, "database").allowMainThreadQueries().build()
return sInstance!!
}
}
现在在任意数量的 activity 或片段中使用此实例,就像那样
{
var allcustomer = MyApplication.mInstanceDB.customerDao.getAll()
}
导出和导入使用这个库
implementation 'com.ajts.androidmads.sqliteimpex:library:1.0.0'
我正在使用 Room Persistence Library 1.1.0。我可以使用 Android Studio 的设备文件资源管理器在 /data/data/<package_name>/databases/
找到数据库文件。
它包含多个 tables,我可以使用 room-DAO
s 毫无问题地访问 tables 的内容。然而,当用 sqlite-browser
打开时,显示没有 table.
可能是什么原因?是否可以在不从房间切换回旧 SQLiteOpenHelper
的情况下解决问题?
解决方案
要用sqlite-browser
打开这样的数据库*,你需要复制所有三个文件。所有都必须在同一目录中。
* 如问题所述,数据库存储在多个文件中。
为什么是三个文件?
根据文档,从版本 1.1.0
开始,Room 使用 write-ahead logging
作为具有足够 RAM 的设备的默认日志模式,并在 API 级别 16 上使用 运行 或更高。在这个版本之前,所有设备都是 Truncate
。 write-ahead logging
与 Truncate
相比具有不同的内部结构。
偶尔看看 SQLite
使用的临时文件 :
直到版本 1.1.0
自版本 1.1.0
如果您想将日志模式明确更改为Truncate
,您可以这样做。但是,不推荐因为WAL
比Truncate
好很多。
public static void initialize(Context context) {
sAppDatabase = Room.databaseBuilder(
context,
AppDatabase.class,
DATABASE_NAME)
.setJournalMode(JournalMode.TRUNCATE).build();
}
是否可以在不更改为 Truncate
的情况下将其移动到单个文件?
是的,是的。针对数据库查询以下语句。
pragma wal_checkpoint(full)
此处详细讨论
您可以使用 wal_checkpoint
pragma 来触发 checkpoint,这会将 WAL 文件事务移回数据库。
theRoomDb.query("pragma wal_checkpoint(full)", null)
或
// the result
// contains 1 row with 3 columns
// busy, log, checkpointed
Cursor cursor = theRoomDb.query("pragma wal_checkpoint(full)", null)
有关 pragma 参数值和结果的更多详细信息,请参阅 PRAGMA Statements。
如果 WAL 未启用,则 pragma 不执行任何操作。 对了,我是用Room 1.1.1测试的,默认没有使用WAL模式,只好开启了。
将 AndroidStudio 中设备文件资源管理器中的所有三个文件复制到您的 PC 目录,并在 SQLite 数据库浏览器中打开 db 文件 (http://sqlitebrowser.org)。确保所有三个文件都在同一个文件夹中。
房间数据库导出和导入解决方案
我在我的一个项目中遇到了同样的问题,我花了两天时间来解决这个问题。
解决方案
Don't create multiple instance for Room library. Multiple instance creating all the problems.
我的应用程序
class MyApplication: Application()
{
companion object {
lateinit var mInstanceDB: AppDatabase
}
override fun onCreate() {
super.onCreate()
mInstanceDB = AppDatabase.getInstance(this)
}
}
AppDatabase
fun getInstance(context: Context): AppDatabase
{
if (sInstance == null) {
sInstance = Room.databaseBuilder(context.applicationContext,AppDatabase::class.java, "database").allowMainThreadQueries().build()
return sInstance!!
}
}
现在在任意数量的 activity 或片段中使用此实例,就像那样
{
var allcustomer = MyApplication.mInstanceDB.customerDao.getAll()
}
导出和导入使用这个库
implementation 'com.ajts.androidmads.sqliteimpex:library:1.0.0'