如何检查数据是否插入房间数据库
How to check if data is inserted in Room Database
我在我的项目中使用来自新架构组件的房间数据库。
我正在通过 dao 添加一些数据,但是在尝试检索它时我没有得到它。你能建议我如何检查插入是否成功吗?以下是帮助您理解问题的代码。
添加到数据库中,我用调试器检查,这条语句执行成功。
appContext.db.rallyDAO().addVehicleListItem(vehicle)
插入此语句后从数据库获取空值。
val v = appContext.db.rallyDAO().getVehicleListItem(it.vehicleID)
房间数据库
@Database(entities = arrayOf(Rally::class, Route::class, CheckPoints::class, Vehicles::class, VehicleListItem::class), version = 1)
abstract class TSDRoom: RoomDatabase() {
public abstract fun rallyDAO():RallyDAO
}
DAO 内部
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem)
@Query("select * from vehicles_submitted where vehicle_id LIKE :vehicleID")
fun getVehicleListItem(vehicleID:String):VehicleListItem
VehicleListItem 实体
@Entity(tableName = "vehicles_submitted",
foreignKeys = arrayOf(ForeignKey(entity = Rally::class,
parentColumns = arrayOf("rally_id"),
childColumns = arrayOf("rally_id"))))
class VehicleListItem {
@PrimaryKey
@ColumnInfo(name = "vehicle_id")
@SerializedName("vehicle_id")
var vehicleID : String = ""
@ColumnInfo(name = "driver_id")
@SerializedName("driver_id")
var driverID : String = ""
@ColumnInfo(name = "vehicle_name")
@SerializedName("vehicle_name")
var vehicleName : String = ""
@ColumnInfo(name = "driver_name")
@SerializedName("driver_name")
var driverName : String = ""
@ColumnInfo(name = "driver_email")
@SerializedName("driver_email")
var driverEmail : String = ""
@ColumnInfo(name = "rally_id")
@SerializedName("rally_id")
var rallyID: String = ""
@ColumnInfo(name = "is_passed")
@SerializedName("is_passed")
var isPassed = false
@ColumnInfo(name = "passing_time")
@SerializedName("passing_time")
var passingTime:String=""
}
如果您没有访问权限问题,您可以考虑的一个选项是直接导航到设备的 sqlite 实例并直接在其中查询表。
如果您使用与 Android Studio 集成的模拟器或 root phone,您可以执行以下操作:
adb root
adb remount
cd data/data/path/of/your/application/database
sqlite3 mydb.db
然后你可以查询你的表
问题出在线程中。
Room 不允许您 运行 在主线程中查询数据库。对 insert 方法的调用在 try-catch 块内,我忽略了异常。
我修复了它,这是它现在的样子。
doAsync {
val addedID = appContext.db.rallyDAO().addVehicleListItem(vehicle)
Logger.d("vehicle_lsit_item","Inserted ID $addedID")
}
此外,我查看了 documentation,插入方法可能 return 一个 Long(或者如果传递给插入的 List,则为 Long 的 List)。我也改了insert的签名,这里是修改后的代码
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem):Long
P.S。我将 anko 用于 doAsync
您可以使用 Android Debug Database 通过网络浏览器访问应用程序的数据库。 Android 调试数据库通过嵌入式 Web 服务器公开数据库。
使用方法如下:
将其作为 debugImplementation
依赖项包含在您应用的 build.gradle
中,以便它仅包含在调试版本中而不包含在发布版本中:
debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'
开始调试您的应用
嵌入式 Web 服务器自动启动并在日志中公布其地址和端口:
D/DebugDB: Open http://XXX.XXX.X.XXX:8080 in your browser
如果您是 运行 USB 应用程序,请设置端口转发:
adb forward tcp:8080 tcp:8080
如果您不是 运行 USB 上的应用程序,您的 Android phone 和工作站需要在同一网络中,并且您的工作站应该能够 ping Androidphone.
最后,在浏览器的日志中打开link。
请注意,由于 Web 服务器在您的应用上下文中运行,因此无需对设备进行 root 操作即可正常工作。
您可以使用 Stetho 在 chrome 开发工具中查看您的数据库和共享 pref 文件
http://facebook.github.io/stetho/
编辑:AS 现在有一个 built-in 数据库工具
您可以通过多种方式进行测试。
- 正如@Ege Kuzubasioglu 提到的,您可以使用 Stetho 手动检查(需要对代码进行微小更改)。
将数据库文件从 "data/data/yourpackage/databases/yourdatabase.db" 拉到您的本地计算机,并使用任何应用程序读取数据库中的内容。我个人使用https://sqlitebrowser.org/。
可以使用 shell 命令或使用 android 工作室的 "Device File Explorer" 来完成提取数据库文件。
编写测试用例以查看其是否工作。这是我的一个项目中的测试用例示例。
// 来自我的 DAO 的代码 class
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract Long[] insertPurchaseHistory(List MusicOrders);
//我的测试用例
@测试
public void insertPurchaseHistoryTest() {
// Read test data from "api-responses/music-purchase-history-response.json"
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream("api-responses/music-purchase-history-response.json");
// Write utility method to convert your stream to a string.
String testData = FileManager.readFileFromStream(inputStream);
// Convert test data to "musicOrdersResponse"
MusicOrdersResponse musicOrdersResponse = new Gson().fromJson(testData,MusicOrdersResponse.class);
// Insert inmateMusicOrders and get the list of
Long[] rowsInserted = tracksDao.insertPurchaseHistory(musicOrdersResponse.getmusicOrders());
assertThat(rowsInserted.length,Matchers.greaterThan(0));
}
我是这样写的(我用协程suspend
):
class SaveVehicle(val repository: RepositoryInterface) {
suspend fun invoke(vehicleListItem: VehicleListItem): VehicleListItem =
with(vehicleListItem) {
also {
repository.saveVehicle(vehicleListItem)
}
}
}
Kotlin 文档
inline fun <T> T.also(block: (T) -> Unit): T
使用此值作为其参数调用指定的功能块,returns此值。
also
适用于执行一些将上下文对象作为参数的操作。 also
用于需要引用对象而不是其属性和函数的操作,或者当您不想从外部范围隐藏此引用时。
你可以查看my example in GitHub:
最简单的方法之一是:
首先在 Android Studio 中下载 DB Navigator 作为插件(更多请访问:https://plugins.jetbrains.com/plugin/1800-database-navigator)。
转到查看 > 工具 Window> 设备文件资源管理器并下载您的数据库实例。
打开数据库浏览器(从左窗格 window)并浏览您下载的数据库实例。设置连接,你就可以浏览你的数据库了。
更多信息请参考上面提供的link。
关于插入有两种情况。
用 @Insert 注释的 Dao 方法 returns:
如果输入的只有一个数字returns一个Long,检查这个Long是否等于1,如果为真则添加Item成功。
@Insert
suspend fun insert( student: Student): Long
如果输入是 varargs 它 returns 一个 LongArray,检查 varargs 的大小是否等于 LongArray 的大小,如果为真则项目添加成功
@Insert
suspend fun insert(vararg students: Student): LongArray
我在我的项目中使用来自新架构组件的房间数据库。 我正在通过 dao 添加一些数据,但是在尝试检索它时我没有得到它。你能建议我如何检查插入是否成功吗?以下是帮助您理解问题的代码。
添加到数据库中,我用调试器检查,这条语句执行成功。
appContext.db.rallyDAO().addVehicleListItem(vehicle)
插入此语句后从数据库获取空值。
val v = appContext.db.rallyDAO().getVehicleListItem(it.vehicleID)
房间数据库
@Database(entities = arrayOf(Rally::class, Route::class, CheckPoints::class, Vehicles::class, VehicleListItem::class), version = 1)
abstract class TSDRoom: RoomDatabase() {
public abstract fun rallyDAO():RallyDAO
}
DAO 内部
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem)
@Query("select * from vehicles_submitted where vehicle_id LIKE :vehicleID")
fun getVehicleListItem(vehicleID:String):VehicleListItem
VehicleListItem 实体
@Entity(tableName = "vehicles_submitted",
foreignKeys = arrayOf(ForeignKey(entity = Rally::class,
parentColumns = arrayOf("rally_id"),
childColumns = arrayOf("rally_id"))))
class VehicleListItem {
@PrimaryKey
@ColumnInfo(name = "vehicle_id")
@SerializedName("vehicle_id")
var vehicleID : String = ""
@ColumnInfo(name = "driver_id")
@SerializedName("driver_id")
var driverID : String = ""
@ColumnInfo(name = "vehicle_name")
@SerializedName("vehicle_name")
var vehicleName : String = ""
@ColumnInfo(name = "driver_name")
@SerializedName("driver_name")
var driverName : String = ""
@ColumnInfo(name = "driver_email")
@SerializedName("driver_email")
var driverEmail : String = ""
@ColumnInfo(name = "rally_id")
@SerializedName("rally_id")
var rallyID: String = ""
@ColumnInfo(name = "is_passed")
@SerializedName("is_passed")
var isPassed = false
@ColumnInfo(name = "passing_time")
@SerializedName("passing_time")
var passingTime:String=""
}
如果您没有访问权限问题,您可以考虑的一个选项是直接导航到设备的 sqlite 实例并直接在其中查询表。
如果您使用与 Android Studio 集成的模拟器或 root phone,您可以执行以下操作:
adb root
adb remount
cd data/data/path/of/your/application/database
sqlite3 mydb.db
然后你可以查询你的表
问题出在线程中。 Room 不允许您 运行 在主线程中查询数据库。对 insert 方法的调用在 try-catch 块内,我忽略了异常。 我修复了它,这是它现在的样子。
doAsync {
val addedID = appContext.db.rallyDAO().addVehicleListItem(vehicle)
Logger.d("vehicle_lsit_item","Inserted ID $addedID")
}
此外,我查看了 documentation,插入方法可能 return 一个 Long(或者如果传递给插入的 List,则为 Long 的 List)。我也改了insert的签名,这里是修改后的代码
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem):Long
P.S。我将 anko 用于 doAsync
您可以使用 Android Debug Database 通过网络浏览器访问应用程序的数据库。 Android 调试数据库通过嵌入式 Web 服务器公开数据库。
使用方法如下:
将其作为
debugImplementation
依赖项包含在您应用的build.gradle
中,以便它仅包含在调试版本中而不包含在发布版本中:debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'
开始调试您的应用
嵌入式 Web 服务器自动启动并在日志中公布其地址和端口:
D/DebugDB: Open http://XXX.XXX.X.XXX:8080 in your browser
如果您是 运行 USB 应用程序,请设置端口转发:
adb forward tcp:8080 tcp:8080
如果您不是 运行 USB 上的应用程序,您的 Android phone 和工作站需要在同一网络中,并且您的工作站应该能够 ping Androidphone.
最后,在浏览器的日志中打开link。
请注意,由于 Web 服务器在您的应用上下文中运行,因此无需对设备进行 root 操作即可正常工作。
您可以使用 Stetho 在 chrome 开发工具中查看您的数据库和共享 pref 文件
http://facebook.github.io/stetho/
编辑:AS 现在有一个 built-in 数据库工具
您可以通过多种方式进行测试。
- 正如@Ege Kuzubasioglu 提到的,您可以使用 Stetho 手动检查(需要对代码进行微小更改)。
将数据库文件从 "data/data/yourpackage/databases/yourdatabase.db" 拉到您的本地计算机,并使用任何应用程序读取数据库中的内容。我个人使用https://sqlitebrowser.org/。 可以使用 shell 命令或使用 android 工作室的 "Device File Explorer" 来完成提取数据库文件。
编写测试用例以查看其是否工作。这是我的一个项目中的测试用例示例。
// 来自我的 DAO 的代码 class
@Insert(onConflict = OnConflictStrategy.REPLACE) public abstract Long[] insertPurchaseHistory(List MusicOrders);
//我的测试用例 @测试 public void insertPurchaseHistoryTest() {
// Read test data from "api-responses/music-purchase-history-response.json"
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream("api-responses/music-purchase-history-response.json");
// Write utility method to convert your stream to a string.
String testData = FileManager.readFileFromStream(inputStream);
// Convert test data to "musicOrdersResponse"
MusicOrdersResponse musicOrdersResponse = new Gson().fromJson(testData,MusicOrdersResponse.class);
// Insert inmateMusicOrders and get the list of
Long[] rowsInserted = tracksDao.insertPurchaseHistory(musicOrdersResponse.getmusicOrders());
assertThat(rowsInserted.length,Matchers.greaterThan(0));
}
我是这样写的(我用协程suspend
):
class SaveVehicle(val repository: RepositoryInterface) {
suspend fun invoke(vehicleListItem: VehicleListItem): VehicleListItem =
with(vehicleListItem) {
also {
repository.saveVehicle(vehicleListItem)
}
}
}
Kotlin 文档
inline fun <T> T.also(block: (T) -> Unit): T
使用此值作为其参数调用指定的功能块,returns此值。
also
适用于执行一些将上下文对象作为参数的操作。 also
用于需要引用对象而不是其属性和函数的操作,或者当您不想从外部范围隐藏此引用时。
你可以查看my example in GitHub:
最简单的方法之一是:
首先在 Android Studio 中下载 DB Navigator 作为插件(更多请访问:https://plugins.jetbrains.com/plugin/1800-database-navigator)。
转到查看 > 工具 Window> 设备文件资源管理器并下载您的数据库实例。
打开数据库浏览器(从左窗格 window)并浏览您下载的数据库实例。设置连接,你就可以浏览你的数据库了。
更多信息请参考上面提供的link。
关于插入有两种情况。
用 @Insert 注释的 Dao 方法 returns:
如果输入的只有一个数字returns一个Long,检查这个Long是否等于1,如果为真则添加Item成功。
@Insert suspend fun insert( student: Student): Long
如果输入是 varargs 它 returns 一个 LongArray,检查 varargs 的大小是否等于 LongArray 的大小,如果为真则项目添加成功
@Insert suspend fun insert(vararg students: Student): LongArray