Room 에서 Log 출력하기

지프치프·2025년 11월 29일

Android

목록 보기
95/95
post-thumbnail

“Android 로봇은 Google에서 제작하여 공유한 저작물을 복제하거나 수정한 것으로 Creative Commons 3.0 저작자 표시 라이선스의 약관에 따라 사용되었습니다.”


개요

개인 프로젝트 앱에 새로운 쿼리를 추가하려는데 의도대로 동작이 안되는 거 같아서
Logging을 해보려는데 @Query@Delete@Update처럼 성공 결과를 반환하지 않으니 Logging을 하기가 애매했다.

그래서 방법을 찾아보았는데 Query 처리에 대한 콜백을 제공하는 것을 발견,
여기서 Log를 찍어보기로 했다.

QueryCallback

이 방법은 Room 2.4.0 버전 이상부터 지원합니다.

우선 사용방법은 아래와 같이 setQueryCallback()이라는 메소드를
Room 객체를 생성할때 Builder에 추가해준다.

        Room.databaseBuilder(
            context,
            MyDatabase::class.java,
            "MyDB.db"
        )
            .addMigrations(*MIGRATIONS)
            .setQueryCallback({ query, args ->
                Log.d("query: $query\t\nargs: $args")
            }, Executors.newSingleThreadExecutor())
            .build()
        /**
         * Sets a [QueryCallback] to be invoked when queries are executed.
         *
         * The callback is invoked whenever a query is executed, note that adding this callback
         * has a small cost and should be avoided in production builds unless needed.
         *
         * A use case for providing a callback is to allow logging executed queries. When the
         * callback implementation logs then it is recommended to use an immediate executor.
         *
         * @param queryCallback The query callback.
         * @param executor The executor on which the query callback will be invoked.
         * @return This builder instance.
         */
        @Suppress("MissingGetterMatchingBuilder")
        open fun setQueryCallback(
            queryCallback: QueryCallback,
            executor: Executor
        ) = apply {
            this.queryCallback = queryCallback
            this.queryCallbackExecutor = executor
        }

매개변수를 보면 QueryCallback, Executor를 요구하는데
핵심은 QueryCallback 다.

    /**
     * Callback interface for when SQLite queries are executed.
     *
     * Can be set using [RoomDatabase.Builder.setQueryCallback].
     */
    fun interface QueryCallback {
        /**
         * Called when a SQL query is executed.
         *
         * @param sqlQuery The SQLite query statement.
         * @param bindArgs Arguments of the query if available, empty list otherwise.
         */
        fun onQuery(sqlQuery: String, bindArgs: List<Any?>)
    }

SQLite가 쿼리를 실행할때 이 인터페이스를 통해 콜백을 전달받는다.
그럼 그 콜백에서 Log를 작성해주면..
쿼리가 실행될때마다 아래와 같이 Log가 출력된다.

23:37:50.733  D  [DHModule.kt::onQuery] query: BEGIN DEFERRED TRANSACTION	
                 args: []
23:37:50.734  D  [DHModule.kt::onQuery] query: INSERT OR IGNORE INTO room_table_modification_log VALUES(1, 0)	
                 args: []
23:37:50.734  D  [DHModule.kt::onQuery] query: CREATE TEMP TRIGGER IF NOT EXISTS `room_table_modification_trigger_charactersentity_UPDATE` AFTER UPDATE ON `charactersentity` BEGIN UPDATE room_table_modification_log SET invalidated = 1 WHERE table_id = 1 AND invalidated = 0; END	
                 args: []
23:37:50.735  D  [DHModule.kt::onQuery] query: CREATE TEMP TRIGGER IF NOT EXISTS `room_table_modification_trigger_charactersentity_DELETE` AFTER DELETE ON `charactersentity` BEGIN UPDATE room_table_modification_log SET invalidated = 1 WHERE table_id = 1 AND invalidated = 0; END	
                 args: []
23:37:50.736  D  [DHModule.kt::onQuery] query: CREATE TEMP TRIGGER IF NOT EXISTS `room_table_modification_trigger_charactersentity_INSERT` AFTER INSERT ON `charactersentity` BEGIN UPDATE room_table_modification_log SET invalidated = 1 WHERE table_id = 1 AND invalidated = 0; END	
                 args: []
23:37:50.737  D  [DHModule.kt::onQuery] query: TRANSACTION SUCCESSFUL	
                 args: []
23:37:50.737  D  [DHModule.kt::onQuery] query: END TRANSACTION	
                 args: []
23:37:50.738  D  [DHModule.kt::onQuery] query: SELECT * FROM CharactersEntity	
                 args: []

보다시피 트랜젝션의 결과도 알려주기 때문에
내가 만든 쿼리와 파라미터, 작동 여부도 모두 확인해 볼 수 있다.

만약 개발중인 앱에 DB 사용량이 많다면 이 방법을 사용해서
Logging을 하는 것도 괜찮을 것으로 생각된다.

개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.

profile
지프처럼 거침없는 개발을 하고싶은 개발자

0개의 댓글