Help us understand the problem. What is going on with this article?

Android Database access

More than 1 year has passed since last update.

AndroidのDB利用手順

  1. DBヘルパークラスを用意し、それをNewすることでヘルパーオブジェクトを生成する。
  2. アクティビティなどで、ヘルパーオブジェクトからDB接続オブジェクト(SQLiteDatabaseObject)を取得する。
  3. DB接続オブジェクトを使ってSQLを実行する。

HelperClass

作成方法

AndroidSDKにはSQLiteOpenHelperがあるが、それを継承して作成しなければならない。

onCreateとonUpgrateとconstructerを記述しないと確実に動作しない、がそれが必要なため、絶対に動かないように設定されいてる。

  • constructer
  • onCreate()
  • onUpgrade()

super(4個引数);<-これがないとコンパイルエラーに
と親クラスのコンストラクタを呼び出すCodeを記述する。
4個の引数は以下の通りとなる

Context context

コンテキストはこのクラス内で用意できないので、このクラスを使うアクティビティなどからもらう必要がある。
->このDBヘルパークラスのコンストラクタの引数としておく必要があり。

example
public DtabaseHelper(Context context){
  super(context, ....)
}

String name

使用するデータベースファイル名

CursorFactory factory

カーソルのファクトリオブジェクト(所謂ResultSet)

基本的にいじらない事が多いのでNullで良い

int version

整数で1始まり

Androidでは内部のDBがバージョン番号とともに、管理されている。
ここで渡す番号より内部の番号が若い(小さい)場合はあ後述のonUpgrade()が自動実行される。

ソフトをアップデートをしたタイミングで走らせるもの。本番運用する際に大事

今日のtips

第二引数のデータベースファイル名と、第四引数のバージョン番号は、このクラスの定数として記述しておく。

定数管理をするとやりやすいよね。

example
/**
 * データベースの名前
 */
private static final String DATABASE_NAME = "example.db";

/**
 * バージョン番号
 */
private static final int DATABASE_VERSION = 1;

onCreate()

内部にデータベースが存在しない時(初期状態)に一回だけ実行されるメソッド。

CREATE TABLE など、初期設定に必要なSQLをここで実行する。引数のdbはDB接続オブジェクトなので、そのメソッドを利用する。

DLL文の実行は execSQL(...) を使用する。

各テーブルの主キーはINTEGER型でカラム名は_idとする。

必要なら、AUTOINCREMENT(連番主キー)とする。

Tips

カラム名の主キーは_idが強制されている。

-> _id だと ○○○_id というふうに文字連結しやすい。

onCreate()の実行は一回だけ 一回だけ、 インストール直後に 一回だけ実行される。(アプリをアンインストールすれば問題ない)

onUpgrade()

以下の、第2、第3引数の違いを利用して、ALTER TABLE などのDB内部の構造を変更する。

引数はonCreate()同様DB接続オブジェクト

第二: oldVersion -> 現在の内部番号

第三: newVersion -> constructorで設定された番号

現在はデータを退避させてテーブルを一から作成させてINSERTを行っているらしい。

データアクセス

基本手順

AndroidでのDB接続手順は以下の通り

  1. ヘルパーオブジェクトを生成する。
  2. ヘルパーからDB接続オブジェクトをもらう。
  3. データ処理を行う(後述)
  4. DB接続オブジェクトを解放する必要がある。(確実に解放しなければならない)

ソースコードのパターンとして以下のようになる。

DatabaseHelper helper = new DatabaseHelper(...); //1
SQLiteDatabase db = helper.getWritableDatabase(); //2

try{
  //dbを使用してデータ処理 3
catch(Exception e){
  //例外処理
}finally{
  db.close();// 4
}

更新系

INSERT/UPDATE/DELETE文の発行手順は、以下の通り。

SQL文字列を作成する。

このとき変数によって値が変わるところを?と記述する。

String sqlDelete = "DELETE FORM .... _id = ?"このような形

ステートメントオブジェクトをもらう

SQLiteStatement stmt = db.compileStatement(sqlDelete);

変数をバインドする

上記に →SQL文字列を作成する で記載した?(プレースホルダ)に値を埋め込む。

stmt.bindLong(数字, 挿入するもの) (各種型のmethodがある)

SQLを実行する

  • INSERT: stmt.executeInsert();
  • UPDATE/DELETE: stmt.executeUpdateDelete();

参照系

SELECT文の発行手順は以下の通り。

SQL文字列を作成する

更新系と違いバインド変数は使いづらいので、変数は文字列結合する。

カーソルをループする

CursorはResultSetと同じようなものなので、同じくループするwhile(cursor.moveToNext(){}表現が明らかに1行の場合はifでも可能

各行のデータを取得する。

カーソルでループする部分で、各行のデータを取得する。

ただし、ResultSetのように、カラム名では、直接取り出すmethodがないので、一度カラムインデックスを取得して使う。

int idxNote = cursor.getColumnIndex("note");
String note = cursor.getString(idxNote);
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away