モバイル チュートリアル:dbExpress と SQLite を使用する(iOS および Android)

提供: RAD Studio
移動先: 案内検索

モバイル チュートリアル:モバイル アプリケーション開発(iOS および Android) への移動


YellowBang.png注意: このチュートリアルで解説されている dbExpress は、廃止予定です。これはつまり、今後のリリースにおいて、dbExpress が RAD Studio から削除されることを意味します。

dbExpress の代わりに、当社の新しいデータベース ソリューションである FireDAC を使用することをお勧めします。FireDAC については、類似のチュートリアル「
モバイル チュートリアル:FireDAC と SQLite を使用する(iOS および Android)」で説明しています。

このチュートリアルを開始する前に、次のチュートリアルを読んで実行してください。

このチュートリアルでは、dbExpress フレームワークによりモバイル デバイス上のローカル データ ストレージとして SQLite を使用する基本手順を説明します。

iOS Android

IOSScreen.png

AndroidScreen.png

dbExpress を使用してデータベースに接続する

dbExpress は、Delphi で書かれた非常に高速なデータベース アクセス フレームワークです。RAD Studio では、InterBase、Oracle、DB2、SQL Server、MySQL、Firebird、SQLite、ODBC など、ほとんどの主要データベース用にドライバを用意しています。データベースは違っても、ここで説明するものと同様の手順でこれらのデータベースにアクセスすることができます。

  • モバイル プラットフォームの場合、dbExpress では InterBase ToGo および SQLite をサポートしています。これらのデータベース製品は iOS および Android デバイス上で動かすことができます。
  • それ以外の Oracle などのデータベースでは、少なくともクライアント ライブラリが必要です。Windows プラットフォームでは、クライアント ライブラリは DLL として提供されていて、それに対して接続します。そのため、モバイル デバイスからこれらのデータベース製品に接続するには、DataSnap などの中間層技術を使ってアプリケーションを開発する必要があります。

モバイル デバイス上でクライアント ライブラリを使用せずにエンタープライズ データベースに接続する方法は、別のチュートリアルで説明しています。「モバイル チュートリアル:モバイル クライアントからエンタープライズ データベースに接続する(iOS および Android)」を参照してください。

Windows 環境で開発用にデータベースを作成する

まず、開発用の Windows プラットフォームで SQLite データベース ファイルを作成します。フォーム デザイナを使ってアプリケーションのユーザー インターフェイスを設計できるよう、以下の手順を実施します。

[データ エクスプローラ]でデータベースを作成する

  1. [データ エクスプローラ][SQLite]ノードを右クリックし、[新規接続を追加]を選択します。
    AddSQLiteConnection.png

  2. 接続の名前を定義します。たとえば「ShoppingList」とします。
    ShoppingListConnection.png

  3. データベース ファイルの場所を指定します。
    DatabaseLocationFile.png

  4. [詳細]ボタンをクリックして[拡張プロパティ]ダイアログ ボックスを開きます。
  5. FailIfMissing プロパティを「False」に変更します。[OK]をクリックして[拡張プロパティ]ダイアログ ボックスを閉じます。
    300

    メモ: FailIfMissing を「False」に設定すると、ファイルが存在しない場合に[データ エクスプローラ]によって新しいデータベース ファイルが作成されます。
  6. [接続の変更]ダイアログ ボックスに戻り、[接続テスト]ボタンをクリックします。この操作を行うと、ファイルが存在しない場合に新しいデータベース ファイルが作成されます。
    ConnectionTest.png
    メモ: 開発用システムに sqlite3.dll が存在することを確認してください。このファイルが存在しない場合は、http://www.sqlite.org/download.html から sqlite3.dll をダウンロードし、システム パス(64 ビット版 Windows であれば C:\Windows\SysWOW64 など)に配置します。

[データ エクスプローラ]でテーブルを作成する

  1. [データ エクスプローラ]で、[SQLite]セクションの ShoppingList ノードをダブルクリックし、[テーブル]を右クリックします。コンテキスト メニューから[テーブルを新規作成]を選択します。
    CreateNewSQLiteTable.png
  2. ShopItem 列の[データ型]を「TEXT」に設定します。
    SQLiteDefineShopItemTable.png
  3. [保存]ボタンをクリックし、テーブル名を指定します(「Item」など)。
    SpecifySQLiteTableNameAsItem.png

ユーザー インターフェイスの設計とセットアップ

ビジュアルな UI コンポーネントをデザイナ上に読み込んだ状態

このチュートリアルでは、1 つの TListBox コンポーネントを UI 要素として使用します。

以下の手順でリスト ボックス コンポーネントなどの UI 要素をセットアップします。

  1. [ファイル|新規作成|マルチデバイス アプリケーション - Delphi] または [ファイル|新規作成|マルチデバイス アプリケーション - C++Builder]を使用して、マルチデバイス アプリケーションを作成します。
  2. フォームに TToolBar をドロップします。
  3. ツールバー コンポーネント上に TButton をドロップし、[オブジェクト インスペクタ]で次のプロパティを設定します。
    • AlignRight に設定します。
    • Name プロパティを ButtonAdd に設定します。
    • StyleLookupaddtoolbutton に設定します。
  4. ツールバー コンポーネント上に TButton をドロップし、[オブジェクト インスペクタ]で次のプロパティを設定します。
    • AlignLeft に設定します。
    • Name プロパティを ButtonDelete に設定します。
    • StyleLookupdeletetoolbutton に設定します。
    • Text を「Delete」に設定します。
    • VisibleFalse に設定します。
  5. ツールバー コンポーネント上に TLabel をドロップし、[オブジェクト インスペクタ]で次のプロパティを設定します。
  6. TListBox コンポーネントをフォームにドロップし、[オブジェクト インスペクタ]で次のプロパティを設定します。
    • Align プロパティを Client に設定して、リスト ボックス コンポーネントがフォーム全体を占めるようにします。

データに接続する

[データ エクスプローラ]で既に定義したデータベース内のデータに接続する基本手順は以下のとおりです。

  1. [データ エクスプローラ]Item テーブルを選択し、フォーム デザイナへとドラッグします。
    DragTableFromDataExplorerToiOSForm.png

    メモ: これによって、2 つのコンポーネント(ShoppinglistConnection: TSQLConnection および ItemTable: TSQLDataSet)がフォーム上に作成されます。
    ShoppingListAndItem2.png

  2. フォームで ShoppinglistConnection コンポーネントを選択し、Connected プロパティを True に変更します。
  3. フォームで ItemTable コンポーネントを選択し、Active プロパティを True に変更します。
  4. [表示|LiveBinding デザイナ]を選択して[LiveBinding デザイナ]を開きます。
  5. ItemTable コンポーネントの ShopItem を選択し、ShopItemListBox1Item.Text にドラッグします。
    ShopItemToListBox.png

この手順を実施すると、アプリケーションのユーザー インターフェイスが SQLite データベースのデータに接続されます。データが既に含まれたテーブルをこのチュートリアルで使用している場合には、これでフォーム デザイナに実際のデータが表示されるはずです。

ユーザーがリストの項目を選択したときに削除ボタンを表示するためのイベント ハンドラを作成する

[Delete]ボタンの Visible プロパティは False に設定されています。そのため、このボタンはデフォルトでエンド ユーザーから見えなくなっています。次のようにすると、ユーザーがリストの項目を選択したときにこのボタンを表示することができます。

  • ListBox1 を選択し、OnItemClick イベント用に以下のイベント ハンドラを定義します。

Delphi の場合:

procedure TForm1.ListBox1ItemClick(const Sender: TCustomListBox;
  const Item: TListBoxItem);
begin
  if ListBox1.Selected <> nil then
    ButtonDelete.Visible := True
  else
    ButtonDelete.Visible := False;
end;

C++Builder の場合:

void __fastcall TForm1::ListBox1ItemClick(const TCustomListBox *Sender,const TListBoxItem *Item)
{
        if (ListBox1->Selected)
                ButtonDelete->Visible = True;
        else
                ButtonDelete->Visible = False;
}

リストにエントリを追加するための追加ボタン用のイベント ハンドラを作成する

データベース接続も構成した状態

次のステップでは、項目をショッピング リストに追加する機能をアプリケーションに追加します。

  1. フォームに TSQLQuery コンポーネントをドロップします。
  2. [オブジェクト インスペクタ]で次のプロパティを設定します。
    • Name プロパティを「SQLQueryInsert」に設定します。
    • SQLConnection プロパティを ShoppinglistConnection に設定します。
    • SQL プロパティを次のように設定します。
      INSERT INTO ITEM (ShopItem) VALUES (:ShopItem)
    • Params プロパティの拡張([...])ボタンを選択します。
    • ShopItem パラメータを選択し、DataTypeftString に設定します。
      EditingShopItemParameter.png

  3. フォーム デザイナで ButtonAdd コンポーネントをダブルクリックします。このイベント ハンドラに次のコードを追加します。

Delphi の場合:

procedure TForm1.ButtonAddClick(Sender: TObject);
begin
  TDialogServiceAsync.InputQuery('Enter New Item', ['Name'], [''], Self.OnInputQuery_Close);
end;

procedure TForm1.OnInputQuery_Close(const AResult: TModalResult; const AValues: array of string);
var
  TaskName: string;
begin
  TaskName := string.Empty;
  if AResult <> mrOk then
    Exit;
  TaskName := AValues[0];
  try
    if not (TaskName.Trim = string.Empty) then
    begin
      SQLQueryInsert.ParamByName('ShopItem').AsString := TaskName;
      SQLQueryInsert.ExecSQL();
      ItemTable.Refresh;
      LinkFillControlToField1.BindList.FillList;
      if ListBox1.Selected <> nil then
        ButtonDelete.Visible := True
      else
        ButtonDelete.Visible := False;
    end;
  except
    on Ex: Exception do
      ShowMessage('Error: ' + Ex.Message);
  end;
end;

Form クラスの private セクション下に次の手続きプロトタイプを宣言します。

private
    procedure OnInputQuery_Close(const AResult: TModalResult; const AValues: array of string);


C++Builder の場合:

C++ で同じ機能を複製するには、追加手順が必要です。

1. TForm1 定義の後に次の型定義を追加します。

typedef void __fastcall (__closure *TInputCloseQueryProcEvent)(const System::Uitypes::TModalResult AResult,
        System::UnicodeString const *AValues, const int AValues_High);

2. 次のクラス定義を追加します。

class InputQueryMethod : public TCppInterfacedObject<TInputCloseQueryProc>
{
private:
    TInputCloseQueryProcEvent Event;

public:
    InputQueryMethod(TInputCloseQueryProcEvent _Event) {
        Event = _Event;
    }

    void __fastcall Invoke(const System::Uitypes::TModalResult AResult,
        System::UnicodeString const *AValues, const int AValues_High) {
        Event(AResult, AValues, AValues_High);
    }
};

3. フォームの private セクション下に次の宣言を追加します。

void __fastcall OnInputQuery_Close(const System::Uitypes::TModalResult AResult,    
    System::UnicodeString const *AValues, const int AValues_High);

4. 実際の関数を追加します。

void __fastcall TForm1::ButtonAddClick(TObject *Sender) {
    String caption = "Caption";
    String Prompts[1];
    Prompts[0] = "Prompt 0";
    String Defaults[1];
    Defaults[0] = "Default 0";
    _di_TInputCloseQueryProc Met = new InputQueryMethod(&OnInputQuery_Close);
    TDialogServiceAsync::InputQuery(
        "caption", Prompts, 0, Defaults, 0, (TInputCloseQueryProc *)Met);
}
void __fastcall TForm1::OnInputQuery_Close(const System::Uitypes::TModalResult AResult,
        System::UnicodeString const *AValues, const int AValues_High) {
    String TaskName;
    TaskName = "";
    if (AResult != mrOk)
        return;
    TaskName = AValues[0];
    try {
        if (TaskName.Trim() != "")
            SQLQueryInsert->ParamByName("ShopItem")->AsString = TaskName;
        SQLQueryInsert->ExecSQL();
        ItemTable->Refresh();
        LinkFillControlToField1->BindList->FillList();
        if (ListBox1->Selected != NULL)
            ButtonDelete->Visible = True;
        else
            ButtonDelete->Visible = False;
    }
    catch (Exception& Ex) {
        ShowMessage("Error: " + Ex.Message);
    }
}

InputQuery 関数は、エンド ユーザーにテキストの入力を求めるダイアログ ボックスを表示します。 この関数は、ユーザーが OK を選択した際に True を返すため、データベースでデータを追加できるのは、ユーザーが OK を選択し、かつテキストにデータが含まれているときのみです。

iOS Android

UsingInputQueryOniOS.PNG

EnterItemAndroid.png

リストからエントリを削除するための削除ボタン用のイベント ハンドラを作成する

次のステップでは、項目をショッピング リストから削除する機能をアプリケーションに追加します。

  1. フォームに TSQLQuery コンポーネントをドロップします。
  2. [オブジェクト インスペクタ]で次のプロパティを設定します。
    • Name プロパティを「SQLQueryDelete」に設定します。
    • SQLConnection プロパティを ShoppinglistConnection に設定します。
    • SQL プロパティを次のように設定します。
      delete from Item where ShopItem = :ShopItem
    • Params プロパティの拡張([...])ボタンを選択します。
    • ShopItem パラメータを選択し、DataTypeftString に設定します。
  3. [構造]ビューで、ButtonDelete コンポーネントを選択します。このイベント ハンドラに次のコードを追加します。

Delphi の場合:

procedure TForm1.ButtonDeleteClick(Sender: TObject);
var
  TaskName: String;
begin
  TaskName := ListBox1.Selected.Text;

  try
    SQLQueryDelete.ParamByName('ShopItem').AsString := TaskName;
    SQLQueryDelete.ExecSQL();
    ItemTable.Refresh;
    LinkFillControlToField1.BindList.FillList;
    if ListBox1.Selected <> nil then
      ButtonDelete.Visible := True
    else
      ButtonDelete.Visible := False;
  except
    on e: Exception do
    begin
      SHowMessage(e.Message);
    end;
  end;
end;

C++Builder の場合:

void __fastcall TForm1::ButtonDeleteClick(TObject *Sender) {
        String TaskName = ListBox1->Selected->Text;
        try {
                SQLQueryDelete->ParamByName("ShopItem")->AsString = TaskName;
                SQLQueryDelete->ExecSQL();
                ItemTable->Refresh();
                LinkFillControlToField1->BindList->FillList();
                if (ListBox1->Selected)
                        ButtonDelete->Visible = True;
                else
                        ButtonDelete->Visible = False;
        }
        catch (Exception &e) {
                ShowMessage(e.Message);
        }
}

モバイル プラットフォーム用にデータベースの配置をセットアップする

ここまでは、デスクトップで SQLite を使用してきました。つまり、実際のデータベースは、ローカルのハード ディスク ドライブ上(C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\Data\shoplist.s3db など)。 モバイル デバイスでは、アプリケーションはサンドボックス化されるため、通常はアプリケーション フォルダ下の Documents フォルダ(iOS デバイスの場合)および internal 記憶域(Android デバイスの場合)にあるデータしか読み書きできません。

モバイル上でローカル データベースに接続するには、以下の作業を実施する必要があります。

  • データベースをモバイル デバイスに配置する。
  • (データベース ファイルに接続するための)構成を、Documents フォルダ(iOS デバイスの場合)または internal 記憶域(Android デバイスの場合)のローカル ファイルにチェックする。

データベース ファイルを配置マネージャに追加し構成する

モバイル上でアプリケーションを実行するには、データベース ファイル(shoplist.s3db)の配置情報をセットアップする必要があります。

  1. データベースは、次の 2 つの方法のいずれかでプロジェクトに追加することができます。
    • プロジェクト マネージャ でプロジェクト名を右クリックし、そのコンテキスト メニューから[追加...]を選択して(または[プロジェクト|プロジェクトに追加...])、[プロジェクトに追加]ダイアログ ボックスに表示させます。データベースの場所 C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\Data まで移動し、データベースの shoplist.s3db を選択し、[開く]をクリックします。
    • データベースの場所 C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\Data まで移動し、データベースの shoplist.s3db をプロジェクト マネージャ内のプロジェクトまでドラック&ドロップします。[はい]をクリックして、プロジェクトへのファイル追加を確定します。
  2. データベース ファイルを追加したら、[機能ファイル]ウィンドウが表示されるので、[キャンセル]をクリックして閉じます。
  3. 配置マネージャを、[プロジェクト|配置]を選択して開きます。
  4. 配置マネージャ上部のターゲット プラットフォームのドロップダウン リストで、[Debug 構成 - iOS デバイス - 32 ビット プラットフォーム][Debug 構成 - iOS デバイス - 64 ビット プラットフォーム]、または、[Debug 構成 - Android プラットフォーム]を選択し、データベース shoplist.s3db がプラットフォームに追加されていることを確認します。
  5. shoplist.s3dbリモート パスが、iOS プラットフォームおよび Android プラットフォーム用にどのように設定されたか確認してください。
    • iOS デバイス プラットフォームの[リモート パス]StartUp\Documents\
    RemotePathiOS2.png

    • Android プラットフォームの[リモート パス]assets\internal\
    RemotePathAndroid.png

このように構成すると、モバイル デバイス上でアプリケーションを実行したときに、マルチデバイス アプリケーションのサンドボックス領域の Documents フォルダ(iOS プラットフォームの場合)または internal 記憶域(Android プラットフォームの場合)にデータベース ファイル(shoplist.s3db)を配置するよう、設定されます。

モバイル プラットフォーム上のローカル データベース ファイルに接続するようコードを変更する

このアプリケーションの基本的な機能の実装はこれで終わりです。 [データ エクスプローラ]で作業をしたときに、Windows 上にデータベース ファイルを作成しました。このデータベース ファイルは、モバイル デバイスにコピーするかその場で作成しなければ、モバイル デバイス上で使用できません。

SQLite のデータベースおよびテーブルは次の手順で作成することができます。

モバイル デバイス上での SQLite データベースの場所を指定する

  1. フォーム デザイナで ShoppinglistConnection コンポーネントを選択します。
  2. [オブジェクト インスペクタ]BeforeConnect イベントをダブルクリックします。
  3. このイベント ハンドラに次のコードを追加します。

Delphi の場合:

procedure TForm1.ShoppinglistConnectionBeforeConnect(Sender: TObject);
begin
  {$IF DEFINED(iOS) or DEFINED(ANDROID)}
  ShoppinglistConnection.Params.Values['ColumnMetadataSupported'] := 'False';
  ShoppinglistConnection.Params.Values['Database'] :=
      TPath.Combine(TPath.GetDocumentsPath, 'shoplist.s3db');
  {$ENDIF}
end;

TPath レコードは System.IOUtils ユニットで宣言されているため、ユニットの uses 句に System.IOUtils を追加する必要があります。

C++Builder の場合:

void __fastcall TForm1::ShoppinglistConnectionBeforeConnect(TObject *Sender) {
        #if defined(_PLAT_IOS) || defined(_PLAT_ANDROID)
        ShoppinglistConnection->Params->Values["ColumnMetadataSupported"] = "False";
        ShoppinglistConnection->Params->Values["Database"] = System::Ioutils::TPath::Combine(System::Ioutils::TPath::GetDocumentsPath(), "shoplist.s3db");
        #endif
}

TPath レコードは、System.IOUtils ライブラリで宣言されているため、ヘッダー ユニットに #include <System.IOUtils.hpp> を追加する必要があります。

テーブルが存在しなければ作成する

SQLite では、CREATE TABLE IF NOT EXISTS 文を使用すると、テーブルが存在しない場合に作成することができます。テーブルの作成は、TSQLConnection コンポーネントがデータベースに接続した後、TSQLDataSet コンポーネントがテーブルに接続する前に行うことができます。手順は以下のとおりです。

  1. フォーム デザイナで ShoppinglistConnection コンポーネントを選択します。
  2. [オブジェクト インスペクタ]AfterConnect イベントをダブルクリックします。
  3. このイベント ハンドラに次のコードを追加します。

Delphi の場合:

procedure TForm1.ShoppinglistConnectionAfterConnect(Sender: TObject);
begin
  ShoppinglistConnection.ExecuteDirect('CREATE TABLE IF NOT EXISTS Item (ShopItem  TEXT NOT NULL)');
end;

C++Builder の場合:

void __fastcall TForm1::ShoppinglistConnectionAfterConnect(TObject *Sender){
        ShoppinglistConnection->ExecuteDirect("CREATE TABLE IF NOT EXISTS Item (ShopItem  TEXT NOT NULL)");
}

モバイル デバイスでのアプリケーションの実行

これで、シミュレータまたは接続したモバイル デバイスの上でアプリケーションを実行する準備ができました。
アプリケーションを実行するには:

  1. [プロジェクト マネージャ]でターゲット プラットフォームを選択します。
    Targets.png
  2. 次のいずれかのコマンドを選択します。
    • [実行|実行]
    • [実行|デバッガを使わずに実行]


iOS Android

IOSScreen.png

AndroidScreen.png


メモ: アプリケーション実行時に問題が発生した場合には、「トラブルシューティング」で説明している手順を実施してください。

関連項目