Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Using RdbPredicates for Complex Queries in RDB Store

2025年09月30日に「Dev.to」が公開したITニュース「Using RdbPredicates for Complex Queries in RDB Store」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

HarmonyOSのRDB Storeでは、RdbPredicatesというAPIを使って複雑なDBクエリを簡単に構築できる。生のSQLではなく、フィルタリング、ソート、ページネーションなどをプログラムで記述可能だ。これにより、コードの可読性、エラー削減、保守性が向上する。

ITニュース解説

システム開発において、アプリケーションが扱うデータを効率的に管理するためにはデータベースが不可欠だ。データベースは、整理された形で情報を保存し、必要な時に素早く取り出せるようにするための仕組みである。特に、企業やサービスで多くのユーザーや商品、取引の情報を扱う場合、リレーショナルデータベース(RDB)がよく利用される。RDBでは、データを「テーブル」と呼ばれる表形式で管理し、複数のテーブルを関連付けて使うことができる。

これらのデータベースから特定の条件に合う情報を探し出したり、更新したり、削除したりする操作は「クエリ」と呼ばれ、通常はSQL(Structured Query Language)という専用の言語を使って実行される。例えば、「売上が1000円以上で、商品カテゴリが『電化製品』の注文を新しい順に10件取得する」といった複雑な条件の場合、SQL文も長くなり、複数の条件やソート、取得件数の制限などを記述する必要がある。このような生(なま)のSQL文字列を直接プログラムの中に書く方法は、記述ミスが起こりやすく、また、後からプログラムを読み返したときにその意図を理解しにくいという問題があった。さらに、条件が少し変更されるたびにSQL文字列を修正しなければならず、保守の面でも手間がかかりがちだった。

このような課題を解決するため、HarmonyOSというオペレーティングシステムでは、「RdbPredicates」という便利な機能が提供されている。RdbPredicatesは、RDB Storeと呼ばれるHarmonyOSのリレーショナルデータベース(内部的には軽量なデータベースであるSQLiteをベースにしている)に対して、クエリを構築するためのAPI(Application Programming Interface)である。このRdbPredicatesを使うと、SQLの文字列を直接書く代わりに、プログラムコードで条件を段階的に組み立てていくことができる。これは、まるでレゴブロックを組み立てるように、必要な条件の部品を一つずつ組み合わせていくイメージに近い。

RdbPredicatesを使うことの最大のメリットは、プログラムの「可読性」が向上することだ。SQL文を読解するよりも、RdbPredicatesで記述されたメソッドの連鎖を見る方が、そのクエリが何を行おうとしているのかを直感的に理解しやすい。また、SQL文字列の記述ミスによるエラーが減り、「保守性」も大きく向上する。開発者は、SQLの細かい文法を気にすることなく、よりアプリケーションのビジネスロジックに集中できるようになる。

RdbPredicatesが提供する主要なAPIは多岐にわたる。例えば、特定の列が特定の値と「等しい」ことを示すequalTo、ある値よりも「大きい」ことを示すgreaterThanや「小さい」ことを示すlessThan、そして指定した二つの値の「間」にあることを示すbetweenなどがある。これらはデータを絞り込むための「フィルタリング条件」として使われる。さらに、特定のリストに含まれるかを確認するinや、部分的な文字列の「パターンマッチング」を行うlike(例えば、「%night%」で「night」を含む文字列を検索する)といった機能もある。検索結果を特定の順序に並べ替えるためのorderByAsc(昇順)やorderByDesc(降順)、そして表示する結果の数を制限するlimitAsや、先頭から何件分をスキップするかを指定するoffsetAsといった「ページネーション」関連の機能も備わっている。他にも、データをグループ化するgroupByや重複を除外するdistinct、特定のインデックスを利用してパフォーマンスを向上させるindexedByなども用意されており、より高度なクエリにも対応できる。

実際にRdbPredicatesを使ってクエリを実行するまでの流れは比較的シンプルだ。まず、アプリケーションが使うRDB Storeを初期化し、データベースに接続する。次に、クエリの対象となるテーブル名を指定してRdbPredicatesのインスタンスを作成する。そして、このRdbPredicatesインスタンスに対して、先ほど説明したequalTolikeandなどのメソッドをチェーン(連結)させて、必要な条件を組み立てていく。複数の条件を組み合わせたい場合はand()or()を使って結合する。最後に、組み立てたRdbPredicatesのオブジェクトを、データベースのqueryupdatedeleteといった操作メソッドに渡すことで、指定した条件に基づいた処理が実行される。処理結果は「結果セット(ResultSet)」として返されるため、そこから必要なデータを取り出してアプリケーションで利用することになる。

提供されたコード例を見てみよう。まず、Tripsというテーブルを作成している部分がある。このテーブルには、旅行の識別子であるid、旅行のテンプレート名を示すtemplate、旅行開始日を表すstart_date、そして旅行の日数を表すdaysといった列が含まれる。start_dateは日付ではなく整数値で格納され、これは一般的にUNIXタイムスタンプのような形式で日付を表現する際に用いられる。

AppDatabaseクラスは、データベースとのやり取りを管理するためのものだ。initializeRDBメソッドでは、trips_database.dbという名前でデータベースファイルを作成・取得し、もしデータベースが初めて作成された(バージョンが0)ならば、先述のTripsテーブルを作成するSQLを実行して、バージョンを1に更新している。

getLatestTwoDayNightTypeTripという非同期メソッドが、RdbPredicatesを使った複雑なクエリの具体例を示している。このメソッドは、「現在の月から2日間続いた最新の『夜』タイプの旅行」を検索する。 具体的には、次のような手順でRdbPredicatesを構築している。

  1. new relationalStore.RdbPredicates('Trips')Tripsテーブルを対象とすることを宣言。
  2. .like('template', '%night%'):「template」列に「night」という文字列を含む行を検索(例:「Movie Night」、「Party Night」など)。
  3. .and():一つ前の条件と次の条件を「かつ(AND)」で結合。
  4. .equalTo('days', 2):「days」列の値が2である行を検索(2日間の旅行)。
  5. .and():再び前の条件と次の条件を「かつ」で結合。
  6. .between('start_date', oneMonthAgo, now):「start_date」列の値が、現在の時刻から30日前までの期間内にある行を検索。
  7. .orderByDesc('id'):結果をid列の降順(新しいものが先)に並べ替える。
  8. .limitAs(1):結果の中から最初の1件だけを取得する。 このように、メソッドを次々に連結していくことで、非常に複雑な条件もわかりやすく記述できるのが特徴だ。

構築されたpredicatesオブジェクトは、this.database.query(predicates, [...列名])メソッドに渡され、指定された条件に合うデータがデータベースから取得される。取得されたデータはresultSetとして返され、while (resultSet.goToNextRow())のループを使って、一行ずつデータを取り出し、TripModelオブジェクトとして整形している。このresultSetから特定の列の値を取得するには、resultSet.getLong(columnIndex)resultSet.getString(columnIndex)のようなメソッドを使う。

データの更新や削除も同様にRdbPredicatesを使うことができる。例えば、特定のIDを持つ複数の旅行の日数を10日に更新したい場合は、new relationalStore.RdbPredicates('Trips').in('id', [101, 102, 103])のようにin句を使って条件を指定し、updateメソッドに渡す。また、ある日付より古い旅行記録をすべて削除したい場合は、lessThan('start_date', oneMonthAgo)のように条件を指定し、deleteメソッドに渡すことで、安全かつ確実に目的のデータを操作できる。

RdbPredicatesは強力なツールだが、利用する上でいくつか注意すべき点もある。一つは「パフォーマンス」だ。特にlike '%term%'のように、検索文字列の先頭にワイルドカード(%)を置くパターンマッチングは、大規模なテーブルでは処理に時間がかかる場合がある。このような場合は、データベースの「インデックス」を適切に設定することで、検索速度を大幅に改善できる。もう一つは「ページネーション」に関してで、limitAsoffsetAsを使って結果の数を制限する際は、必ずorderByAscorderByDescでソート順を指定することが重要だ。これを怠ると、クエリを実行するたびに結果の並び順が異なってしまい、期待通りのページングが行えない可能性があるためだ。また、複数の条件をequalToで何度もチェーンするよりも、in([...])を使って一度に複数の値を指定する方が、コードの可読性と保守性が向上することがある。

このように、RdbPredicatesはシステムエンジニアを目指す皆さんにとって、データベース操作をよりシンプルでエラーの少ないものにするための非常に有用なツールとなる。SQLの知識はもちろん重要だが、このようなAPIを利用することで、より効率的かつ安全にアプリケーションを開発できるようになるだろう。

関連コンテンツ

関連IT用語