Room で @Query に suspend をつける理由
Room で @Query に suspend をつけるかどうかは大きな設計ポイントになります。ポイントをまとめておきます。
suspend 関数にするメリット
1. DB アクセスをメインスレッドで実行しない保証
Room は DB アクセスをメインスレッドで実行すると
⇒ android.os.NetworkOnMainThreadException
のようにクラッシュする仕組みになっています。
suspend にしておくと、必ずコルーチン内で呼び出す必要があるため、UI を止めずに安全に DB にアクセスできます。
2. 直感的に「1回だけ値を取得」できる
suspend fun getNoteById(id: Int): Note?
→ 呼び出しごとに「その時点のデータ」を取得して返す
データを1回だけ使いたいときに便利
(例: 詳細画面を開くときだけ1レコードを取ってくる)。
3. バックグラウンドで安全に実行
viewModelScope.launch { ... } や
withContext(Dispatchers.IO) { ... }
の中で呼ぶと、自動的に IO スレッド で処理される。
重い処理(数万件の SELECT や INSERT)でも UI がカクつかない。
4. シンプルな API
Flow / LiveData を返すほどでもない「単発処理」には suspend が一番シンプルです。
注意点
常にコルーチンが必要になる
呼び出し側は必ず launch や async が必要。
「UI から直に呼んで値を返す」ことはできない。
リアルタイム監視には不向き
DB の変更を監視したいなら Flow
まとめ
suspend → その時だけ 1 回値を取得(詳細画面、確認用など)
Flow / LiveData → DB の更新をリアルタイム監視(リスト表示、UI バインドなど)