import android.database.sqlite.sqlitedatabase.cursorfactory; public class DatabaseHelper extends SQLiteOpenHelper { /* データベース名 */ private final static

Similar documents
Microsoft Word - Android_SQLite講座_画面800×1280

日 力力 生 行行 入 入 力力 生 用 方

Microsoft Word - Android_SQLite講座_画面800×1280

テーブルの確認 sqlite>.tables.tables コマンドでデータベース内のテーブル一覧を表示する テーブルスキーマの表示 sqlite>.schema mytable.schema コマンドで指定のテーブルのスキーマを表示できる テーブル出力の整形.explain コマンドを使うと テー

補足資料 インテントによるアプリケーションとアクティビティの呼出し Android アプリのキモとなるインテントとは何? インテント ( 呼び出し要求 ) とは Android 独自の機能です 簡単にいえばアプリケーションや他のアクティビティを呼び出す機能ですが 他のアプリケーションを機能や扱えるデ

android2.indd

Taro-korattsu.jtd

ファイルを直接編集する画面を切り替えることができる. 図 3 標準のレイアウトを削除する (2) グラフィカル レイアウト画面で LinearLayout(Vertical) を追加するパレットウィンドウの レイアウト の中にある LinearLayout(Vertical) をドラッグして, 編集

Hello, Android

2-2. TableLayout TableLayout は任意のビューを表形式で配置したい場合に利用する (HTML の Table に近いイメー ジ ) 2-3. FrameLayout ビューを重ねて表示するためのレイアウト 後から配置した部品が前面に来る仕様となっている 3. まとめ レイア

データベースからデータの 読 み 込 み Cursorクラス

Prog2_2nd

Prog2_2nd

Prog2_10th

そして 取得した OutputStream インスタンスを使い 文字コードは UTF-8 として PrintWriter インスタンスを生成して あとは PrintWriter.append() で書き込みたい文字 列を渡して close() で保存する というだけです ファイルの読込み方法 それで

補足資料 キーイベント処理サンプル package jp.co.keyevent; import android.app.activity; import android.os.bundle; import android.view.keyevent; import android.widget.t

プログラミング基礎I(再)

Microsoft Word - Android_DI講座_画面800×1280

非推奨メソッド等の掲載について

Android でサービスしよう! 日本 Android の会 2 月 21 日大阪セミナ- 有山圭二 ( 有限会社シーリス )

Prog2_6th

Prog2_6th

mazec テクニカルガイド第5版(Android版)

26 editor.putint(pref_count_key, executecount); 27 // 変更した Preference を確定させる 28 editor.commit(); 29 } (c) 実行の様子実装して実行した様子を図 1 と図 2 に示す. 一度実行するごとに, カウン

Prog2_10th

Microsoft PowerPoint ppt


ボタンイベントアプリイベント処理を含むアプリとして, ボタンをもち, ボタンを押すと文字列を表示するアプリを作る. このアプリは,HelloWorld アプリを改造して作成するため, アプリ作成の途中からの手順を示す. 1. ボタンの設置 (1) レイアウトにボタンを追加するパレットの フォーム ウ

2 // TODO Auto-generated method stub float x = event.getx(); float y = event.gety(); String action = ""; switch(event.getaction()) { case MotionEvent.

Prog2_6th

Microsoft Word - Android_DI講座_画面800×1280

GEC-Java

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版  

Javaプログラムの実行手順

1: Preference Display 1 package sample. pref ; 2 3 import android. app. Activity ; 4 import android. content. Intent ; 5 import android. content. Shar

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

Microsoft Word - _Intent.doc

Prog2_9th

Another Activity オブジェクトは生成されてもいないのである これは 後述の onpause メソッ ドの説明からも明らかである 翻訳 : A の onpause から返ってこない限り B は create されない ため ここで長い処理は行ってはならない 実際にトレースをおこなってみ

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

Taro-twokansu3.jtd

intra-mart Accel Platform — イベントナビゲータ 開発ガイド   初版   None

Prog2_5th

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

PowerPoint プレゼンテーション

データベースアクセス

スライド 1

MasterDetailFlow SettingsActivity 2. Android Lint Checks 以前のバージョンよりコンパイルのチェックが厳しくなりました このような厳しいチェックを Android Lint Checks と言います Abdroid プログラミング Bible で

第1章 ビジュアルプログラミング入門

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint - prog09.ppt

Microsoft PowerPoint - prog09.ppt

PowerPoint プレゼンテーション

Brekeke PBX - Version 2.1 ARSプラグイン開発ガイド

Prog2_12th

マルチ OS エンジンを使用した固定記憶域の操作 (テクノロジー・プレビュー) - パート 2

データアダプタ概要

標準化 補足資料

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

Microsoft PowerPoint pptx

Android Layout SDK プログラミング マニュアル

JavaプログラミングⅠ

Prog1_15th

Microsoft Word - Android_DI講座_画面800×1280


PowerPoint プレゼンテーション

目次 更新履歴... 1 はじめに... 3 レコードセット?... 3 準備... 5 SQL でデータを取得する... 6 データのループ処理... 7 列の値を取得する... 7 対象行を変更する (MoveFirst, MoveNext, MovePrevious, MoveLast)...

Prog1_6th

玉転がしタブレット端末の特徴の一つとして, センサを使った動作や, 指による画面操作がある. それらを活用して, 図形を動かすアプリの例を示す. 1. プロジェクトを作る Tama アプリケーションを作る,Tama プロジェクトを作る. 図 1 プロジェクト作成 プロジェクトの構成を設定する. 図

eラーニング資料 e ラーニングの制作目標 データベース編 41 ページデータベースの基本となる概要を以下に示す この内容のコースで eラーニングコンテンツを作成予定 データベース管理 コンピュータで行われる基本的なデータに対する処理は 次の 4 種類です 新しいデータを追加する 既存のデータを探索

Seasar.NET入門

JAVA入門

PowerPoint プレゼンテーション

メソッドのまとめ

IT プロジェクト

PowerPoint Presentation

10th Developer Camp - B5

2

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

Prog1_10th

プロジェクト毎に名前を指定する ( ここでは AndroidTest) 動作可能な最低バージョン メインターゲットのバージョン すべて設定してクリック チェックを外す クリック

Javaの作成の前に

JAVA とテンプレート

PowerPoint プレゼンテーション

Microsoft PowerPoint - ruby_instruction.ppt

文字列操作と正規表現

Microsoft認定資格問題集(70-483_demo)

Microsoft Word - VBA基礎(6).docx

Java知識テスト問題

tkk0408nari

プログラミング入門1

TestDesign for Web

Java言語 第1回

メディプロ1 Javaプログラミング補足資料.ppt

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

メール全文検索アプリケーション Sylph-Searcher のご紹介 SRA OSS, Inc. 日本支社技術部チーフエンジニア Sylpheed 開発者 山本博之 Copyright 2007 SRA OSS, Inc. Japan All right

Microsoft PowerPoint - db03-5.ppt

Microsoft PowerPoint - OOP.pptx

intra-mart Accel Platform — IM-共通マスタ スマートフォン拡張プログラミングガイド   初版  

Transcription:

Android データベース処理の便利 ( ヘルパー ) クラスの利用 SQLiteOpenHelper クラス 必ずしもこのヘルパークラスは利用する必要はないのですが 利用すると以下のような利 点があります このクラスを使うと発生する3つの利点 ) 1 指定したデータベースファイルが存在していないときは自動的にファイル生成を行う事ができる 2 DB オープン時 もしテーブルが存在していないときは自動的にテーブル生成を行う事ができる 3 テーブルのバージョンアップが感知でき 既存のテーブルやデータの更新を指示通りにやってくれる サンプル ) 新規プロジェクト設定プロジェクト名 :UseDBHelperAndroid ターゲット :1.5 アプリケーション名 :UseDBHelperAndroid パッケージ名 :db.helper Create Activity:MainActivity バージョン :3 DB 管理ヘルパークラス (DatabaseHelper.java) を別途定義します SQLiteOpenHelper を継承します 後は このヘルパークラスを Activity 系クラス内で生成し利用するだけです package db.helper; import android.content.context; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqliteopenhelper; 1

import android.database.sqlite.sqlitedatabase.cursorfactory; public class DatabaseHelper extends SQLiteOpenHelper { /* データベース名 */ private final static String DB_NAME = "androidstudydb"; /* データベースのバージョン */ private final static int DB_VER = 1; /* * バージョンアップした際に呼び出すコンストラクタ * 第 2 引数で バージョン番号を指定できる onupgrade() の引数 newversion に渡される * 以前のバージョン番号より上がっていると onupgrade() が自動的に呼ばれる */ DatabaseHelper(Context context, int version) { super(context, DB_NAME, null, version); /* * 初回テーブル生成時に利用するコンストラクタ * バージョン番号は1で設定される */ public DatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VER); /* * oncreate メソッドデータベースが作成された時に呼ばれます * テーブルの作成などを行います * 今回は MyTable という名前のテーブルを1つ作成しています */ @Override public void oncreate(sqlitedatabase db) { // テーブル作成の SQL 文 2

String sql = ""; sql += "create table MyTable ("; sql += " No integer primary key autoincrement"; sql += ",Name text not null"; sql += ",Tel text"; sql += ",Age integer"; sql += ")"; db.execsql(sql);//sql 実行 /* * onupgrade メソッド onupgrade() メソッドはデータベースをバージョンアップした時に呼ばれます * 現在のレコードを退避し テーブルを再作成した後 退避したレコードを戻すなどの処理を行います */ @Override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { // 今回 更新処理内容は決めていないので 未実装 main.xml ( レイアウトファイル ) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/buttoninsert" android:text="insert"> </Button> 3

<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/buttonupdate" android:text="update"> </Button> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/buttondelete" android:text="delete"> </Button> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/buttonselect" android:text="select"> </Button> </LinearLayout> データベースにデータを登録 更新 削除を行う画面系クラスです (MainActivty.java) package db.helper; import android.app.activity; import android.content.contentvalues; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import android.os.bundle; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.toast; public class MainActivity extends Activity { private DatabaseHelper dbhelper; 4

@Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); // ボタンに Click リスナーを設定する Button buttoninsert = (Button) this.findviewbyid(r.id.buttoninsert); buttoninsert.setonclicklistener(buttoninsert_clicklistener); Button buttonupdate = (Button) this.findviewbyid(r.id.buttonupdate); buttonupdate.setonclicklistener(buttonupdate_clicklistener); Button buttondelete = (Button) this.findviewbyid(r.id.buttondelete); buttondelete.setonclicklistener(buttondelete_clicklistener); Button buttonselect = (Button) this.findviewbyid(r.id.buttonselect); buttonselect.setonclicklistener(buttonselect_clicklistener); // ここでヘルパークラスを生成 dbhelper = new DatabaseHelper(this); /* Insert ボタンの Click リスナー クラス名のない無名内部クラス形式でイベント処理を定義 */ private OnClickListener buttoninsert_clicklistener = new OnClickListener() { public void onclick(view v) { buttoninsert_click(v);// 下記に定義した insert メソッドを呼ぶ ; /* Update ボタンの Click リスナー */ private OnClickListener buttonupdate_clicklistener = new OnClickListener() { public void onclick(view v) { buttonupdate_click(v); ; /* Delete ボタンの Click リスナー */ private OnClickListener buttondelete_clicklistener = new OnClickListener() { public void onclick(view v) { 5

buttondelete_click(v); ; /* Select ボタンの Click リスナー */ private OnClickListener buttonselect_clicklistener = new OnClickListener() { public void onclick(view v) { buttonselect_click(v); ; /* * Insert ボタン Click 処理 */ private void buttoninsert_click(view v) { // 列名と値をペアで管理する ContentValues オブジェクトを利用 // 名前 電話番号 年令をセットする ContentValues values = new ContentValues(); // 本来は以下の値をユーザに入力してもうらように作成するのだが 便宜的に値を用意 values.put("name", "yan"); values.put("tel", "0000-1234-5678"); values.put("age", 18); // 書き込みモードで DB に接続し オープンする // 書き込みモードはデータの排他制御が自動的に行われる SQLiteDatabase db = dbhelper.getwritabledatabase(); // 処理したレコード ID long ret; // 列名のスペルミス等によりインサートに失敗すると -1 を返す仕様 ret = db.insert("mytable", null, values); db.close();// DB 接続を解除 6

if (ret == -1) { Toast.makeText(this, "Insert 失敗 ", Toast.LENGTH_SHORT).show(); else { Toast.makeText(this, "Insert 成功 :" + ret + " 件 ", Toast.LENGTH_SHORT).show(); /* * Update ボタン Click 処理 */ private void buttonupdate_click(view v) { ContentValues values = new ContentValues(); values.put("age", 24);// set Age=24 に変更 String whereclause = "No =?";// 更新する列名を指定 String whereargs[] = new String[1];// 更新する列の値を指定 whereargs[0] = "1";// No が 1 の行を更新 SQLiteDatabase db = dbhelper.getwritabledatabase(); // 処理したレコード件数 int ret; // update from MyTable set Age=24 where No=1; と同じ ret = db.update("mytable", values, whereclause, whereargs); db.close(); if (ret == -1) { Toast.makeText(this, "Update 失敗 ", Toast.LENGTH_SHORT).show(); else { Toast.makeText(this, "Update 成功 :" + ret + " 件 ", Toast.LENGTH_SHORT).show(); 7

/* Delete ボタン Click 処理 */ private void buttondelete_click(view v) { String whereclause = "No =?"; String whereargs[] = new String[1]; whereargs[0] = "1"; SQLiteDatabase db = dbhelper.getwritabledatabase(); // 処理したレコード件数 int ret; // delete from MyTable where No=1; と同じ ret = db.delete("mytable", whereclause, whereargs); db.close(); if (ret == -1) { Toast.makeText(this, "Delete 失敗 ", Toast.LENGTH_SHORT).show(); else { Toast.makeText(this, "Delete 成功 :" + ret + " 件 ", Toast.LENGTH_SHORT).show(); 定 /* Select ボタン Click 処理 */ private void buttonselect_click(view v) { String[] columns = { "Name", "Tel", "Age" ;// 表示する列名を配列で指 String where = "No =?";// 検索キ の列名を指定 String[] param = { "1" ;// 検索キ の値を指定 // 検索なので読み込み専用で DB を開く 8

SQLiteDatabase db = dbhelper.getreadabledatabase(); // 検索実行 Cursor curs = db.query("mytable", columns, where, param, null, null, "No desc", "10"); // 検索データ詰め込み用 StringBuilder selectdata = new StringBuilder(0);// 初期サイズは 0 文字 while (curs.movetonext()) { // 列データの取り出し String name = curs.getstring(0); String tel = curs.getstring(1); int age = curs.getint(2); selectdata.append(name + ":" + tel + ":" + age + " 才 " + " n"); if (selectdata.length()!= 0) { Toast.makeText(this, selectdata, Toast.LENGTH_LONG).show(); else {// 初期サイズの 0 文字だったら Toast.makeText(this, " 検索結果はありませんでした ", Toast.LENGTH_LONG).show(); db.close(); ポイント解説 コードを見てみましょう 例えば 以下のようなクラスを実装します class SubOpenHelper extends SQLiteOpenHelper{ // コンストラクタ引数 :Activity 系オブジェクト引数 : データベースのファイル名引数 : 整数のバージョン番号 9

public SubOpenHelper(Context c,string dbname,int version){ super(c,dbname,null,version); // コールバックメソッドこのクラスが利用されるとき自動的に呼ばれる public void oncreate(sqlitedatabase db){ db.execsql( create table - 省略 - ); // コンストラクタで新しいバージョン番号が指定されると自動的に呼ばれる public void onupgrade( SQLiteDatabase db,int oldversion,int newversion){ 実装例 // 現在のレコードを取得して 一旦メモリへ退避 // テーブルの削除 // 新しくテーブルを作り直して // メモリへ退避させたレコードを挿入する etc コンストラクタ まずはコンストラクタを見ましょう スーパークラスのコンストラクタを呼び出してます 第一引数は Context 型インスタンスです 自身のアプリを示す場合は getapplicationcontext() を使って生成します 第二引数は DB ファイル名です 第四引数は DB のバージョンで 作成するときに指定できます 例えば テーブルの仕様を変えた後であれば この数値を上げてやる という使い方が出来ます 第 3 引数には CursorFactory 型インスタンスを渡すのですが とりあえず普通に使う分には使わないので null でいいです ( 私も良く知らないので もし余力があれば調べて 別記事で紹介します ) oncreate メソッド このインスタンスを使ってデータベースをオープンする時に もし指定されたデータベー 10

スが無い場合に 自動的に実行されるメソッドです ここでは このデータベースで使用するテーブルの Create 文の発行を行えばよいでしょう その他 デフォルトで入れておきたいレコードがあれば挿入してやるなどの処理も行えます 既にデータベースが存在しているときに このインスタンスが生成されたとしても実行されません onupgrade メソッド データベースのバージョンが上がったときに自動的に実行されるメソッドです このインスタンスを使ってデータベースをオープンするときに コンストラクタで渡したバージョンと 実際に存在しているデータベースのバージョンが違うときに呼び出され 古いバージョンの値と 新しいバージョンの値は引数としても渡されてきます サンプルコードでは 処理の実体を書いていませんが 例えば テーブルの仕様を変えたという想定ですと 一旦データを取り出しておいてメモリに持たせておき 今のテーブルを消して 新しくテーブルを作り直して 取り出しておいたレコードをちゃんと挿入しなおす という処理を行う事ができます 不必要なら処理を書かなくてもいいですが 定義をしておかないとコンパイルが通りません このような形で SQLiteOpenHelper のメソッドをオーバーライド実装しておきます データベースのオープン処理 では 次は 最初に行うべきデータベースのオープン処理をみてみましょう 以下のようなコードになります SQLiteDatabase sdb; SubOpenHelper helper = new SubOpenHelper(this, test.db,1); sdb = helper.getwritabledatabase(); // もしくは //sdb = helper.getreadabledatabase(); まずは 先ほど実装した SQLiteOpenHelper のサブクラスのインスタンスを生成します そして そのインスタンスの getwritabledatabase() メソッドを使って データベースを 11

オープンします 読み取り専用でいいときは getreadabledatabase() でも使用できます getwritabledatabase() もしくは getreadabledatabase() メソッドの戻り値 SQLiteDatabase 型インスタンスを使って レコードの挿入や削除 検索を行っていきます レコードの追加方法 それではまず レコード追加時のサンプルコードを見てみましょう なお テーブル定義は テーブル名は bookmarklist で _id 列と bookmark 列の 2 列が存在する事とします _id 列については 別記事 Android アプリで使用する SQLite のテーブル作成時の注意点 を参照してください ContentValues values = new ContentValues(); values.put( bookmark, http://android.roof-balcony.com ); long id = sdb.insert( bookmarklist, null, values); if (id < 0){ // 処理失敗時の処理を行う レコードの追加は SQLiteDatabase.insert() メソッドを使います 第一引数はテーブル名です 第二引数はちょっと飛ばして 第三引数は挿入するレコードの内容を格納した ContentValues 型インスタンスを渡します 列名をキーとして 値を put() メソッドで渡します 今回は一つですが 必要なカラム数分だけ put() メソッドを実行しましょう 第二引数は API リファレンスの英文をよくみましたが不明です insert() メソッドの戻り値は id に設定された数値となります -1 が返却された場合は エラーを示します エラー時は 警告を出すなど エラーに必要な処理を行って下さい 12

レコードの更新方法 次は レコード更新のサンプルコードについてみてみましょう String id = 1 ; ContentValues values = new ContentValues(); values.put( bookmark, http://freegame.roof-balcony.com ); sdb.update( bookmarklist, values, _id=?, new String[]{id); レコードの更新は SQLiteDatabase.update() メソッドを使います 第一引数は レコードの更新を行うテーブル名を指定します 第二引数は レコード追加時と同じく ContentValues 型インスタンスを設定します 詳しくは先ほどのレコード追加時の説明を見てください 第三引数は SQL の where 句 つまり更新するレコードの条件にするカラムを指定します サンプルコードのように? を付ける事で この後で指定する第四引数の配列にあたる条件が代入されて SQL が生成されます これらの処理を SQL で表現すると 以下のようになります update bookmarklist set bookmark = http://freegame.roof-balcony.com where _id = 1 update() メソッドの戻り値は 実際更新されたレコード数が返却されます レコードの削除方法 次は レコード削除のサンプルコードについてみてみましょう String id = 1 ; sdb.delete( bookmarklist, _id =?, new String[]{id); レコードの更新は SQLiteDatabase.delete() メソッドを使います 第一引数は レコードの更新を行うテーブル名を指定します 第二引数 第三引数は 先ほどの更新 (update) と同じく 条件を指定します delete() の戻り値は 削除されたレコード数が戻ります これも update() 同様 API リファレンスには エラー時の動作については書かれていませ 13

んでした なお 上記の処理を SQL 文にすると 以下のようになります delete from bookmarklist where _id = 1 SQL 文をそのまま実行する方法 これまでのように レコードの追加は insert() 更新は update() 削除は delete() の各メソッドを使用する方法もありますが SQLiteDatabase クラスには SQL 文をそのまま実行してくれるメソッドもあります それが SQLiteDatabase.execSQL() です SQL が得意な方は この execsql() の方が使いやすいと思います 例えば 先ほどの例のレコード更新の場合だと 以下のようなコードになります String sqlstr = update bookmarklist + set bookmark = http://freegame.roof-balcony.com + where _id = 1 sdb.execsql(sqlstr); これなら SQL 文さえ理解しておけば 全て execsql() で実装できます 更新や削除の際 複雑な条件文を指定するのであれば SQL 文の状態で処理を行った方が簡単ではないかなと思います 注意事項ですが この execsql() は select 文は使えません レコードの追加 更新 削除や テーブルの作成 削除にはこの execsql() が使えます select 文の場合は rowquery() や query() メソッドしか使えません レコードの検索 SQL でいう select 文 レコードの検索について説明していきます 一概にはいえませんが データベースを取り扱う上で コード的には最も実装する場面が多いのが この select ではないかと思います 既に SQLiteDatabase 型インスタンスを生成しているものとします 変数名は sdb とします なお テーブル定義は テーブル名は bookmarklist で _id 列と bookmark 列の 2 列が存在する事とします 14

レコードの検索を行った後 検索結果は Cursor というインスタンスとして返されてきます この Cursor インスタンスの取得方法は 大きく 2 通りありますので まずはその方法を紹介します SQLiteDatabase.query() の使い方 まずは一つ目の SQLiteDatabase.query() メソッドの使い方を説明します final String[] columns = new String[]{ _id, bookmark ; String where = bookmark like? ; String param = %android% ; Cursor c = sdb.query( bookmarklist,columns,where,new String[]{param, null,null, _id desc, 10 ); SQLiteDatabase.query() メソッドの第一引数はテーブル名です 第二引数は 取得する列名 ( カラム名 フィールド名 ) の配列を指定します 第三引数 第四引数は取得するレコードの条件を指定します 今回は bookmark 列の文字列に android という文言が含まれる文字列 という条件にしています 第五引数は group by 句を指定します 第六引数は Having 句を指定します 第七引数は order by 句を指定します 第八引数は limit 句 ( 取得するレコードの上限数 ) を指定します 使わない場合は null を指定します 今回の処理を SQL 文で表現すると 以下のようになります select _id,bookmark from bookmarklist where bookmark like %android% order by _id desc limit 10 SQLiteDatabase.rowQuery() の使い方 15

それでは次は rowquery() メソッドの使い方を説明します rowquery() メソッドは 文字通り 生のクエリを使用します String sqlstr = select _id,bookmark + from bookmarklist + where bookmark like %android% + order by _id desc + limit 10 ; Cursor c = sdb.rowquery(sqlstr); SQLiteDatabase.rowQuery() メソッドの引数は SQL 文です 個人的には 先ほどの query() メソッドより使いやすいと思うんですが どうでしょうか query() メソッドは どの引数に何のパラメータを与えればよかったんだっけ? といちいち調べないといけなさそうなのですが rowquery() メソッドは明確です それに inner join や left outer join 等を使って 複数テーブルを結合させるような SQL だったら この rowquery() の方がいいでしょう Android アプリで使われる程度の SQL は難しいとは思えませんので 生の SQL を実行できる rowquery() の方が 可読性もいいのではないかと思います 初めての Android P.166~P.177 を見ながら実装せよ プロジェクト名 :Event2 アプリケーション名 :Event2 パッケージ :org.example.events Create Activity:Events ターゲット :1.5 バージョン :3 リソースファイル res/layout に以下 2 ファイルを作成 16

main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- 'list' と 'empty' のための組み込み ID に注意 --> <ListView android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/empty" /> </LinearLayout> item.xml ( リストアイテムの表示レイアウトを別途定義したもの ) <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" android:padding="10sp"> <TextView android:id="@+id/rowid" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/rowidcolon" android:layout_width="wrap_content" 17

android:layout_height="wrap_content" android:text=": " android:layout_torightof="@id/rowid" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@id/rowidcolon" /> <TextView android:id="@+id/timecolon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=": " android:layout_torightof="@id/time" /> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ellipsize="end" android:singleline="true" android:textstyle="italic" android:layout_torightof="@id/timecolon" /> </RelativeLayout> リソースファイル res/values に以下 1 ファイルを作成 strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">events</string> <string name="empty">no events!</string> </resources> 18

Constants.java ( 定数宣言用インターフェース BaseColumns はコンテントプロバイ ダー使用時に必要だが 今回は使用せず テキストサンプルの Event3 で利用されている ) package org.example.events; import android.provider.basecolumns; public interface Constants extends BaseColumns { // テーブル名 public static final String TABLE_NAME = "events"; // Events データベースのカラム public static final String TIME = "time";// 日時 public static final String TITLE = "title";// イベントのタイトル EventsData.java ( データベースヘルパークラス ) package org.example.events; import static android.provider.basecolumns._id; import static org.example.events.constants.table_name; import static org.example.events.constants.time; import static org.example.events.constants.title; import android.content.context; import android.database.sqlite.sqlitedatabase; import android.database.sqlite.sqliteopenhelper; public class EventsData extends SQLiteOpenHelper { private static final String DATABASE_NAME = "events.db"; private static final int DATABASE_VERSION = 1; /** Events データベースのためのヘルパーオブジェクトを作る */ public EventsData(Context ctx) { super(ctx, DATABASE_NAME, null, DATABASE_VERSION); 19

@Override public void oncreate(sqlitedatabase db) { db.execsql("create TABLE " + TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + TIME + " INTEGER," + TITLE + " TEXT NOT NULL);"); @Override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { // 仮の更新処理 : テーブルの削除と新規作成 db.execsql("drop TABLE IF EXISTS " + TABLE_NAME); oncreate(db); Events.java ( デフォルトでリストが組み込まれた画面用クラス ) package org.example.events; import static android.provider.basecolumns._id; import static org.example.events.constants.table_name; import static org.example.events.constants.time; import static org.example.events.constants.title; import android.app.listactivity; import android.content.contentvalues; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import android.os.bundle; import android.widget.simplecursoradapter; // ListActivity クラスを継承 public class Events extends ListActivity { 20

// 表示対象のテーブルの列名 private static String[] FROM = { _ID, TIME, TITLE, ; //TIME で降順 ( ソートのルールで使用 ) private static String ORDER_BY = TIME + " DESC"; // 表示するテキストビューの id を列挙 private static int[] TO = { R.id.rowid, R.id.time, R.id.title, ; private EventsData events; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); // データベースヘルパークラスを利用 events = new EventsData(this); try { addevent("hello, Android!");// レコード追加 Cursor cursor = getevents();// 検索結果取得 showevents(cursor);// 画面にリスト表示 finally {// この try finally は安全に確実にクローズするための記述です! events.close(); // データ追加用メソッド private void addevent(string string) { // Events データソースに新しいレコードを挿入する // 削除 更新も同様の方法で実行できる SQLiteDatabase db = events.getwritabledatabase(); ContentValues values = new ContentValues(); values.put(time, System.currentTimeMillis()); values.put(title, string); 21

db.insertorthrow(table_name, null, values); // 検索用メソッド private Cursor getevents() { // 管理されたクエリーを実行する Activity は クローズの他 // 必要な場合は再クエリーを処理する SQLiteDatabase db = events.getreadabledatabase(); Cursor cursor = db.query(table_name, FROM, null, null, null, null, ORDER_BY); startmanagingcursor(cursor); return cursor; // リスト表示メソッド item.xml を参照して表示形式を決定している private void showevents(cursor cursor) { // データバインド ( リスト画面に検索結果を貼り付け ) をセットアップする SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, FROM, TO); setlistadapter(adapter); ListActivity とは? ListActivity はリスト表示専用のアクティビティクラスで アクティビティの内部に ListView オブジェクトを内包しています 新たに ListView ウィジェットを作成して アクティビティに配置する必要がありません 内部の ListView オブジェクトに Adapter オブジェクトを指定するには setlistadapter メソッドを使います 22

ListActivity にレイアウトファイルを指定する ListActivity も 通常のアクティビティのようにレイアウトファイルを指定する事ができますが レイアウトファイルには守らなければならないきまりがあります レイアウトファイルの ListView の ID には 固定の ID android:list を指定します また ListActivity にレイアウトファイルを指定すると リストの表示項目が無い場合に リストのかわりにメッセージを自動的に表示させる事ができます この メッセージを表示するウィジェットの ID には 固定の ID android:empty を指定します 以下にその例を示します レイアウトファイル (main.xml) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=" リスト表示のサンプル " /> <ListView android:id="@+id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#00ff00" /> <TextView android:id="@+id/android:empty" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text=" データが存在しません " 23

android:background="#ff0000" /> </LinearLayout> 24