2020-04-07
先日、Roomを使った検索履歴機能を実装していた時のお話。
Roomのドキュメントに沿って、
1. Entityを実装
@Entity(tableName = "search_keyword_history")
data class SearchKeywordHistoryEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val keyword: String,
val createdAt: Long = System.currentTimeMillis(),
var updatedAt: Long = System.currentTimeMillis()
)
2. DAO(Database Access Object)を実装
@Dao
interface SearchKeywordHistoryDao {
@Insert
suspend fun insert(entity: SearchKeywordHistoryEntity)
@Update
suspend fun update(entity: SearchKeywordHistoryEntity)
@Query("DELETE FROM search_keyword_history WHERE keyword LIKE :keyword")
suspend fun deleteKeyword(keyword: String)
// キーワードを降順で取得する
@Query("SELECT keyword FROM search_keyword_history ORDER BY updatedAt DESC")
suspend fun getKeywords(): List<SearchKeywordHistoryEntity>
// クエリに部分一致するキーワードを降順で取得する
@Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>
// クエリに完全一致するキーワードを見つける
@Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?
}
3. Databaseを実装
@Database(entities = [SearchKeywordHistoryEntity::class], version = 1)
abstract class SearchHistoryDatabase : RoomDatabase() {
abstract fun searchKeywordHistoryDao(): SearchKeywordHistoryDao
}
さて、ロジックは実装できたので、一旦ビルドしましょう。
ところがビルドエラーが発生。 以下ログ。
> Task :app:kaptStagingDebugKotlin
e: hogeBinding.java:32: エラー: シンボルを見つけられません
e: fugaBinding.java:57: エラー: シンボルを見つけられません
e: hogehogeBinding.java:68 エラー: シンボルを見つけられません
e: fugafugaBinding.java:77 エラー: シンボルを見つけられません
~ 略 ~
...?
DataBindingでシンボル未解決エラー?
特にレイアウトやバインドする変数を改変した覚えはないのだが...
その後も原因究明に徹するもレイアウトファイルに異常はなく。
Logcatにもヒントがなく、いよいよ良く分からんな...と匙をぶん投げていた。
そして何気なくコードを眺めていたらふと気付く。
/** SearchKeywordHistoryDao.kt **/
// キーワードを降順で取得する
@Query("SELECT keyword FROM search_keyword_history ORDER BY updatedAt DESC")
suspend fun getKeywords(): List<SearchKeywordHistoryEntity>
// クエリに部分一致するキーワードを降順で取得する
@Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>
// クエリに完全一致するキーワードを見つける
@Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?
あれ、Query文間違ってね?
SELECT keyword
だとEntityを取得できないからEntity返せないですね。
これを正しくEntityを返せるように、Query文を書き直し。
/** SearchKeywordHistoryDao.kt **/
// キーワードを降順で取得する
@Query("SELECT * FROM search_keyword_history ORDER BY updatedAt DESC")
suspend fun getKeywords(): List<SearchKeywordHistoryEntity>
// クエリに部分一致するキーワードを降順で取得する
@Query("SELECT * FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>
// クエリに完全一致するキーワードを見つける
@Query("SELECT * FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?
そして何となくビルド。
えっ...うそ...やだ...通った...
原因はQuery文のミスでした。
ログも汎用的なBindingのシンボル未解決エラーだったし、こんなの気づくわけないよ...うん...というわけで今回備忘録的に記事を書きました。
参考になる方がいらっしゃれば幸いです。
じゃ、そゆことで。