Android Room 数据库 DAO 调试日志

标签 android logging android-room

给定这样的 Room 数据库 DAO:

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Query;

import java.util.Date;
import java.util.List;

@Dao
public interface MyDao {

    @Query("SELECT * FROM MyTable")
    List<MyItem> all();

    @Query("SELECT * FROM MyTable WHERE date = :date AND language = :language")
    MyItem byDate(Date date, String language);


}

有没有办法将 Logger 或类似的东西添加到 MyDao 以便我可以看到正在执行哪些语句。这在开发过程中非常有用,因为我可以立即检查函数是否正确转换为预期的 SQL 语句。

最佳答案

假设 Room 使用框架的 Sqlite 作为底层数据库,可以很简单地记录语句。唯一的限制:这只能在 emulator 上完成。

来自 SQLiteDebug.java :

/**
 * Controls the printing of SQL statements as they are executed.
 *
 * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
 */
public static final boolean DEBUG_SQL_STATEMENTS =
        Log.isLoggable("SQLiteStatements", Log.VERBOSE);  

默认情况下,log.tag.SQLiteStatements 的值未设置:

alex@mbpro:~$ adb shell getprop log.tag.SQLiteStatements
<-- BLANK LINE -->

根据上面的文档,设置我们必须使用的属性:

alex@mbpro:~$ adb shell setprop log.tag.SQLiteStatements VERBOSE
alex@mbpro:~$ adb shell getprop log.tag.SQLiteStatements
VERBOSE

如我们所见,VERBOSE 值已成功设置。但是,如果我们重新运行我们的应用程序 - 我们将不会看到打印这些语句。为了使它工作,我们必须 restart all the services使用 adb shell stop 然后 adb shell start
如果您尝试使用普通设备执行此操作,您将收到以下错误(已尝试使用 Pixel XL/stock Android 9):

alex@mbpro:~$ adb shell start
start: must be root
alex@mbpro:~$ adb root
adbd cannot run as root in production builds

这就是我们必须使用模拟器的原因:

alex@mbpro:~$ adb root
restarting adbd as root
alex@mbpro:~$ adb shell stop
alex@mbpro:~$ adb shell start

模拟器将重新启动。
运行你的应用程序,你会在 logcat 中看到类似的 Sqlite 语句:

<redacted..>
V/SQLiteStatements: <redacted>/my_db: "BEGIN EXCLUSIVE;"
V/SQLiteStatements: <redacted>/my_db: "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)"
V/SQLiteStatements: <redacted>/my_db: "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, "3cb5664b6da264c13388292d98141843")"
V/SQLiteStatements: <redacted>/my_db: "CREATE TABLE IF NOT EXISTS `MyTable` (`id` TEXT NOT NULL, `date` INTEGER, `language` TEXT, PRIMARY KEY(`id`))"
<redacted..>
V/SQLiteStatements: <redacted>/my_db: "BEGIN EXCLUSIVE;"
V/SQLiteStatements: <redacted>/my_db: "PRAGMA temp_store = MEMORY;"
V/SQLiteStatements: <redacted>/my_db: "PRAGMA recursive_triggers='ON';"
V/SQLiteStatements: <redacted>/my_db: "CREATE TEMP TABLE room_table_modification_log(version INTEGER PRIMARY KEY AUTOINCREMENT, table_id INTEGER)"
V/SQLiteStatements: <redacted>/my_db: "COMMIT;"
<redacted..>
V/SQLiteStatements: <redacted>/my_db: "SELECT * FROM MyTable"
V/SQLiteStatements: <redacted>/my_db: "SELECT * FROM MyTable WHERE date = 1551562171387 AND language = 'en'"  

要撤消更改,请使用以下命令:

alex@mbpro:~$ adb shell setprop log.tag.SQLiteStatements ""
alex@mbpro:~$ adb shell getprop log.tag.SQLiteStatements
<-- BLANK LINE -->
alex@mbpro:~$ adb shell stop
alex@mbpro:~$ adb shell start
alex@mbpro:~$ adb unroot
restarting adbd as non root

关于Android Room 数据库 DAO 调试日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46172417/

相关文章:

android - 从 WSDL 中查找 SOAPAction

java - 使用 java 读取部署的 jar 文件夹之外的日志文件

java - 在 edittext onclick 上设置日历时出现错误

java - android jni返回多个变量

android - 如何在 Android 中获取位置及其温度?

c# - 是否可以在 C#/.Net 中将消息记录到 cmd.exe?

java - timeBasedFileNamingAndTriggeringPolicy 中的 MaxFileSize 不起作用?

android - 房间数据库: Multiple delete query crashes app

java - 有没有办法为房间持久性库创建通用 DAO 类

java - 无法预填充 Room 数据库并在 RecyclerView 上查看它