Android端末でデータベースサーバーにアクセス
前回、予告したように今回は私たちが作ったDBGrid for AndroidとJDBC Driver over HTTP for Androidの紹介です。これらのプログラミングコンポーネントは、すべてのソースコードが提供され、開発者は無償で生産物の再配布ができます。
間違いのないように言っておくと、この記事はAndroid内蔵のデータベースSQLLiteを操作する方法を紹介するためのものではありません。OracleやMySQL、Microsoft SQL Serverといったデータベースサーバーに、Androidクライアントからアクセスする方法を解説するものです。
データベースベンダーが提供するJDBCドライバは、Android機での動作を想定していないということは前回書きました。JDBC Driver over HTTP for Android(以下 JDBC for Android)は、現在のそのような状況下で、今すぐAndroid端末をクライアントとしてデータベースサーバーにアクセスするプログラムを開発するために提供されます。
また、2010年12月時点で公開されているAndroidのデータベースプログラミング情報のほとんどは、表形式のデータ編集を扱っていません。それを実現するのがDBGrid for Androidです。このDBグリッドはJDBCのResultSetオブジェクトとの連結機能を持つため、2行のプログラムコードで結果セットの表示と編集が可能になります。
サンプルプログラムを構成するクラス群
いきなりですが、サンプルプログラムを見てください。リスト1を実行した画面が図1です。今回提供するサンプルプログラムは以下のクラスから構成されます。
- ExDBクラス(サンプルプログラム)
- DBGridクラス(DBGrid for Android)
- droidbクラス(サーバーコンポーネント)
- Connectionクラス(以下 JDBC Driver over HTTP for Android)
- ResultSetクラス
- DriverManagerクラス
- ResultSetMetaDataクラス
- Statemenクラス
リスト1は、ExDBクラスに含まれるプログラムコードの全文です。
データベースプログラミングをするには、どのクラスを修正すればいいのか
最初のExDBクラスがデータベースプログラミングのサンプルプログラムです。読者がデータベースクライアントプログラムを作るときは、このExDBクラスを改変するとよいでしょう。これで最低限のデータベースプログラムは作成できます。ですが、2番目のDBGridクラスに実装されているDBGrid for Androidは、十分なプログラミングインターフェイスを備えていません。だから、実用になるプログラムを作ろうとしたら、このDBグリッドのソースを改変することが必須となります。
DBGrid for Androidはソースコードの改変で機能を変更可能
DBGrid for Androidのソースコードはコメントを含め400行程度のものなので、それを理解してプログラミングすれば、データグリッド系のコンポーネントよりも柔軟なプログラミングが可能です。ゆえに私たちは、そのようなプログラミングスタイルを提案します。カプセル化することでプログラミングの柔軟性に制限を加える必要もないでしょう。
大体、ちょっと高機能なデータグリッドコンポーネントのマニュアルは何百ページもあったりするので、それを習得する学習コストも決して少なくありません。本連載や私たちのホームページでも、DBGrid for Androidを改変するプログラミング情報を提供していきます。
サーバーコンポーネント
droidbクラスは、Webサーバーに配置されるサーブレットです。JDBC for AndroidはWebブラウザのふりをして、このサーブレットにクライアントの要求を送信します。要求を受け取ったdroidbサーブレットは、通常のJDBCドライバをつかってデータベースにアクセスします。このクラスは、データベースプログラムを開発するためには、通常変更する必要はありません。
JDBC for Androidを実装するクラス
Connectionクラス以降のクラスはJDBC for Androidの実装です。これらは不具合や機能不足がない限り、開発者は触れる必要はありません。データベースベンダーのJDBCドライバとの互換性を考えれば、勝手な機能拡張はしないほうがよいでしょう。とはいえ、JDBC for Androidも独自実装の部分はあります。例えばJDBC for Androidは、他のJDBCドライバと違い、ステートレスのHTTPを通じて動作します。そのためデータベースのロックができません。そこでデータ取得後から編集したデータを書き込むまでのあいだに、もし他のユーザーがデータを編集していたら、データベースへの変更を拒否する仕組みがあります。
JDBC for Androidのクラスはソースコードの改変を前提としていないので、これらのクラスを別パッケージにして、データベースベンダーが提供するJDBCドライバと同様に扱ってもよいです。でも、せっかくソースコードもあるのだから、プロジェクトに組み込んだほうが見通しがよくてよいでしょう。それにそのほうがコンポーネントのバグに対する修正も早くなります。
できるだけ新しいサンプルを
今回、提供するこれらのクラスが市販のコンポーネントのように、すんなり、今すぐ簡単に確実に使えるものだと想像しているならば、その期待は早く捨てた方がよいです。大体、今すぐにAndroid用のデータベースクライアントプログラムを書かなければいけないという人も多くはないでしょう。この連載が続いていく間に、つまり、そのようなプログラムを作らなければならなくなるころには、みなさんのスキルの向上も含め、十分に使えるようなものになっているはずです。
また、もし今すぐにAndroid用のデータベースクライアントプログラムを作らないといけないとしても、他にいい選択肢もないはずです。苦労しても、これらのコンポーネントを使いこなす価値があることは約束します。少なくともスクラッチから書き起こすよりは、時間の節約になるはずです。
これらのコンポーネントの最新情報は、次のWebページで提供します。
サンプルプログラムのダウンロード
この記事のサンプルプログラムをダウンロードして実行するには、Webサーバー、データベースサーバー、およびデータベース(テーブルを含む)を用意する必要があります。またテーブルやデータベースサーバーに合わせて、サンプルプログラム(リスト1)の接続文字列やSELECTステートメントの内容を変える必要があります。
ダウンロード可能なサンプルプログラムのインストール方法を説明する前に、次のページではデータベースプログラムの実装であるExDBクラス(リスト1)の内容を説明します。
package exDB.jar; import android.app.Activity; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.EditText; import android.widget.HorizontalScrollView; import android.view.View; import android.widget.Button; import android.widget.ScrollView; import android.widget.Toast; //import java.sql.DriverManager; //import java.sql.Connection; //import java.sql.ResultSet; public class ExDB extends Activity implements View.OnClickListener { public static Button cmdButton; public static EditText editText; private Connection conn; private ResultSet rSet = null; private DBGrid dBGrid; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout linearLayout=new LinearLayout(this); linearLayout.setOrientation(linearLayout.VERTICAL); cmdButton = new Button(this); cmdButton.setText("バッチ更新"); cmdButton.setHeight(15); cmdButton.setOnClickListener(this); try { // Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/northwind;http://10.0.2.2/droiddb/servlet/jdbchttp", "user", "password"); conn.setAutoCommit(false); rSet = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE) .executeQuery("SELECT CustomerID,CompanyName,ContactName,Address FROM Customers"); } catch(Exception e) { } dBGrid = new DBGrid(this); dBGrid.ColumnTitleList = "ID,取引先名,担当者,住所"; dBGrid.CreateGrid(rSet); linearLayout.addView(cmdButton); HorizontalScrollView hScrollView = new HorizontalScrollView(this); ScrollView scrollView = new ScrollView(this); hScrollView.addView(dBGrid); scrollView.addView(hScrollView); linearLayout.addView(scrollView); setContentView(linearLayout); }//onCreate(Bundle savedInstanceState) public void onClick(View view) { if (view==cmdButton) { //現在編集中の列をDBに反映させるため。 dBGrid.update(); conn.commit(); Toast.makeText(this, "データの更新が完了しました", Toast.LENGTH_SHORT).show(); } }//onClick(View view) }