• 検索結果がありません。

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

N/A
N/A
Protected

Academic year: 2021

シェア "データベースからデータの 読 み 込 み Cursorクラス"

Copied!
26
0
0

読み込み中.... (全文を見る)

全文

(1)

アンドロイドのデータベースについて

SQlite

(2)

データベースからデータの読み込み

Cursorクラス

(3)

//例えばこんなデータベースがあるとして(SQLiteOpenHelperクラスを継承したもの) Database dataBase = new Database(context);

//データベースからとってくるカラム final String[] PROJECTION = { Database.ID , Database.NAME }; //データベースからデータをCursorで取ってくる Cursorでデータをとってきます。 //注意 定数でDatabaseクラスの中にあるとします public static final String ID = "__id";

(4)

//カラムは何番目かをとってくる

int idxID = c.getColumnIndex(Database.ID);

int idxName = c.getColumnIndex(Database.NAME); //これを忘れると、カーソル-1番目から始まってエラー c.moveToFirst(); if ( c.getCount() > 0 ) //カーソルのデータ数取得 { do { int id = c.getInt(idxID);

String name = c.getString(idxName); //なにかの処理 } while ( c.moveToNext() ); } //クローズしないとリーク! c.close(); CursorをmoveToFirst()を最初にやって、 moveToNext()で次のデータへ進めます。 Cursorはイテレータです。

(5)

//データベースからとってくるカラム final String[] PROJECTION = { Database.ID , Database.NAME }; SQLiteDatabase.query( テーブル名 , カラムの名前が入ったString配列 (上のPROJECTION) , クエリー , SelectionArgs(String配列) , GroupBy , Having , ソート順 ); >クエリの発行 ( SQLiteDatabaseクラス ) SelectionArgsはクエリーのところで、“ID = ? or price = ?”として String[] selectionArgs = { “10” , “100” }; を設定すると、? のとこが左から順に置き換わる。 ID = 10 or Price = 100 となる この順番でCursorに値がはいる

(6)

>Cursorについて カーソルのインデックス番号0番に戻す moveToFirst() カーソルのインデックス番号を次へ進める moveToNext() カーソルのインデックス番号をNum番まで進める MoveToPosition( Num ) カーソルのRowの数を得る(データの数) getCount() カラム番号の値をそれぞれの型で受け取る getInt( カラム番号 ) getString( カラム番号 ) getFloat( カラム番号 ) getBoolean( カラム番号 ) カーソルのカラム名から、何番目にアクセスすればいいかを得る getColumnIndex( カラムの名前(String) ) カーソルを閉じる close()

(7)

Cursorをクローズしなければ、DDMSで表示されます。

緑文字(info)なので、メモリリークにはなってないかもしれません。 (OS1.6では赤字(error)でleak found!と表示されていた)

(8)

Cursorからデータを取ってくるとき、インデックスの番号で取得 することになります。2通りの方法があります。

①カラムの番号を直接いれる

String name = Cursor.getString(1);

②最初に一度、カラムの番号をカラム名で問い合わせておく (Database.Nameはstatic final String Name = “_name”;) Int idxName = Cursor.getColumnIndex( Database.Name ); String name = Cursor.getString( idxName );

結果は同じですが・・・

①はあとでソースを見たときにさっぱりわからない。 ②がお勧めです。

(9)

Cursorの中身をデバッグなどで簡単に表示したい場合 Logクラスを使用すると、ログ出力できます。DDMSなどで確認できます。 しかし、自前でログ出力を作りたくない・・・・そんなとき! ログ出力の際に、Cursorの中身をログ出力してくれる便利なクラス android.database.DatabaseUtils.dumpCursor(cursor); ログ出力の 中身

(10)

Cursorを自分で作りたい場合

final String[] projection = { "id","color" };

MatrixCursor c = new MatrixCursor(projection); c.addRow( new Object[]{ 1,"blue" });

c.addRow( new Object[]{ 2,"red" }); c.addRow( new Object[]{ 3,"green" }); c.addRow( new Object[]{ 4,"pink" }); c.addRow( new Object[]{ 5,"white" });

MatrixCursorを使えば作れますが・・・・ なかなか用途は思いつきません(汗

(11)

データベースクラスの作り方

(12)

データベースを操作する前段階として、面倒な問題があります。 データベースのファイルはすでに存在するか ない場合は、ファイル作成、テーブル作成 データベースのバージョンは同じか 同じでないなら、アップグレード(テーブル、カラムの追加等) Cursorでデータの読み出し

(13)

SQLiteOpenHelperクラスはそれをやってくれます。 public class Database extends SQLiteOpenHelper {

public Database(Context context, String name, CursorFactory factory,int version) { super(context, name, factory, version);

// name は、ファイル名(ファイル名のみ!ファイルパス付は不可) // factory は不明(汗

// version はデータベースバージョン(自分で決める) }

@Override

public void onCreate(SQLiteDatabase db) { // ファイルがない場合に呼ばれる

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // バージョンが違うときに呼ばれる

(14)

データベースのファイルはすでに存在するか ない場合は、ファイル作成、テーブル作成 データベースのバージョンは同じか 同じでないなら、アップグレード(テーブル、カラムの追加等) Cursorでデータの読み出し onCreate() OnUpgrade() SQLiteOpenHelperを実装したとき

(15)

端末内のデータベースファイルからの読み出しか、 メモリ上のデータベースしか操作できない、

data/data/ アプリ / databaseにあるdata.dbを使う New Database( context , “data.db” , null , 1 ); メモリ上だけで使う

New Database( context , null , null , 1 );

OnUpgrade()でアップグレード処理を書いても、 インストールされたときはonCreate()しか呼ばれない onCreate()に最終的なバージョンのテーブル作成 などの処理を書かないと、インストールした人はみ んな開いた瞬間エラー! 注意点

(16)

public class Database extends SQLiteOpenHelper { protected SQLiteDatabase mWritable = null; protected SQLiteDatabase mReadable = null;

public Database(Context context, String name, CursorFactory factory,int version) { super(context, name, factory, version);

mWritable = getWritableDatabase(); mReadable = getReadableDatabase(); }

//以下はSQLiteHelperクラスには用意されていない 自作です

public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {

Cursor c = mReadable.query(table, columns, selection, selectionArgs, groupBy, having, orderBy); c.moveToFirst();

return c; }

public void update(String table, ContentValues values, String whereClause) {

mWritable.update(table, values, whereClause, null); }

public void insert(String table, ContentValues values) {

mWritable.insert(table, null , values); }

public void delete(String table, String whereClause) {

(17)

public Database(Context context, String name, CursorFactory factory,int version) { super(context, name, factory, version);

mWritable = getWritableDatabase(); mReadable = getReadableDatabase(); }

@Override

public synchronized void close() { super.close();

mWritable.close(); mReadable.close(); }

(18)
(19)

定期的にこれしないと、deleteされたデータなんかが残って、ファイルサイズが でかくなります

public void vacuum() {

mWritable.execSQL("vacuum"); }

(20)

高速にデータを取り出して、加工して、挿入! db.beginTransaction();

try {

SQLiteStatement stmt = db.compileStatement("insert into table values (?);");

for (String s : array) { stmt.bindString(1, s); stmt.executeInsert(); }   //これを呼びださなければ、ロールバックされる db.setTransactionSuccessful(); } finally { db.endTransaction(); }

(21)

ContentsProvider

Cursorクラス

(22)

public class main extends Activity { @Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //SDカードの曲を取得 Cursor c = this.getContentResolver().query( android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);

コンテンツプロバイダを使えば、1行で簡単取得! URIで、データを取得できます。

(23)

マニュフェストファイルに、URIを書きこむ!

<provider android:authorities="jp.test.testDatabase" android:name=".DataProvider" />

ContentProviderを継承して、Query , insert , update などのメソッドを書くだけで使え ます!

public class DataProvider extends ContentProvider { @Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

}

@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

(24)

Query , Insert , update , delete 以外にもなにかやりたければ、 URIにごりごり追加して、URI解析してやります。

URIMATCHER = new UriMatcher(UriMatcher.NO_MATCH); URIMATCHER.addURI(AUTHORITY, "ほかの処理1", 1); URIMATCHER.addURI(AUTHORITY, "ほかの処理2", 2); int type = URIMATCHER.match(uri);

switch ( type ) { Case 1: ほかの処理1 break; Case 2: ほかの処理2 break; }

(25)
(26)

参照

関連したドキュメント

Although I admittedly do not understand string theory from a physical point of view, I do think (most of my colleagues from algebraic QFT do not share such optimistic ideas) that

That is, we want to know if we can generalize Jacobsthal numbers, to express the number of occurrences of each digit in each shortest repeating string in the b-ary g-Collatz

So consider an arbitrary string s ∈ T , and imagine writing, after each initial segment, the number of left minus right parentheses in that segment.. gambling terminology, this count

ユーザ情報を 入力してくだ さい。必要に 応じて複数(2 つ目)のメー ルアドレスが 登録できます。.

※ログイン後最初に表示 される申込メニュー画面 の「ユーザ情報変更」ボタ ンより事前にメールアド レスをご登録いただきま

申込共通① 申込共通② 申込共通③ 申込共通④ 申込完了

帰ってから “Crossing the Mississippi” を読み返してみると,「ミ

具体音出現パターン パターン パターンからみた パターン からみた からみた音声置換 からみた 音声置換 音声置換の 音声置換 の の考察