[Android] SQLiteOpenHelperでデータベースを読み書きする

SQLiteデータベースの読み書きを勉強したメモ

参考:SQLiteOpenHelper | Android Developers

とりあえず書いてみたコード

  • SQLiteOpenHelperを継承したサブクラスを作成する。このサブクラスはデータベースを開いたり作ったりアップグレードしたり、データベース読み書きをするためのSQLiteDatabaseインスタンスを返したりする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
package jp.fernweh;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class Z095 extends Activity implements OnClickListener {

Button mBtnWrite, mBtnRead;
EditText mTextArea;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);

mBtnWrite = new Button(this);
mBtnWrite.setText("書き込む");
mBtnWrite.setOnClickListener(this);
layout.addView(mBtnWrite);

mBtnRead = new Button(this);
mBtnRead.setText("読み込む");
mBtnRead.setOnClickListener(this);
layout.addView(mBtnRead);

mTextArea = new EditText(this);
layout.addView(mTextArea);
}

// SQLiteOpenHelper は抽象クラスであり、
// 2つの抽象メソッド onCreate, onUpgrade を持つため
// これらを実装しなければならない。
private class MySQLiteOpenHelper extends SQLiteOpenHelper {

Context mContext;

// 引数の無いコンストラクタが無いため作成しなければならない
// コンストラクタで接続するデータベースを指定する
public MySQLiteOpenHelper(Context context, String name,
CursorFactory factory, int version)
{

super(context, name, factory, version);
mContext = context;
}

@Override
public void onCreate(SQLiteDatabase db) {
// データベース作成時(
// SQLDatabase#getWritableDatabase()
// SQLDatabase#getReadableDatabase()
// が成功したとき)にコールされる

Toast.makeText(mContext, "onCreate", Toast.LENGTH_LONG).show();

// データベース処理開始
db.beginTransaction();
try {
// テーブル作成を実行
db.execSQL("CREATE TABLE TABLE_NAME ( ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_KEY);");
db.setTransactionSuccessful();
} finally {
// データベース終了処理
db.endTransaction();
}

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// バージョンが上がったときにコールされる
Toast.makeText(mContext, "onUpgrade", Toast.LENGTH_LONG).show();

db.execSQL("DROP TABLE IF EXISTS test_table");
onCreate(db);
}

@Override
public void onOpen(SQLiteDatabase db) {
// データベースが開かれたときに実行される
// これの実装は任意
super.onOpen(db);
Toast.makeText(mContext, "onOpen", Toast.LENGTH_LONG).show();
}

}

SQLiteOpenHelper mHelper;

// スタート時と、onPause, onStop からの復帰時
@Override
protected void onResume() {
super.onResume();

Toast.makeText(this, "onResume", Toast.LENGTH_LONG).show();

// SQLiteOpenHelperインスタンスを取得するための情報
// コンテキスト
Context CONTEXT = this;
// データベース名 / メモリ上で使用する場合は null
String DATABASE_NAME = "mydatabase.sqlite3";
// CursorFactory : Cursorを作成するためのインスタンス
CursorFactory CURSOR_FACTORY = null;
// バージョン、1から始まる。
// バージョンが変更されたときにコールされる
// onUpgrade と onDowngrade の引数に渡される
int DATABASE_VERSION = 1;

// MySQLiteOpenHelperインスタンスを生成
mHelper = new MySQLiteOpenHelper(CONTEXT, DATABASE_NAME,
CURSOR_FACTORY, DATABASE_VERSION);
}

SQLiteDatabase mWritableDb;
// SQLiteDatabase mReadableDb;

// onPause時にデータベースを閉じる
@Override
protected void onPause() {
super.onPause();

Toast.makeText(this, "onPause", Toast.LENGTH_LONG).show();

mHelper.close();

if (mWritableDb != null) {
Toast.makeText(this, "close mWritableDb", Toast.LENGTH_LONG).show();
mWritableDb.close();
// mReadableDb.close();
}
}

@Override
public void onClick(View v) {
// SQLiteOpenHelper#getWritableDatabase() で
// データベースを開いて、書き込み用の SQLiteDatabase# を取得
// じゃなかった。こいつは読み書き両方できる
// データベースが無ければ作成するが、この場合
// SQLiteOpenHelper#onCreate(SQLiteDatabase db)
// がコールされる
if (mWritableDb == null || mWritableDb.isOpen() == false) {
try {
// mHelper.close();
mWritableDb = mHelper.getWritableDatabase();
// String text = mWritableDb.isOpen() ? "open": "not open" ;
// Toast.makeText(this, text,
// Toast.LENGTH_LONG).show();
} catch (SQLiteException e) {
Toast.makeText(this, "失敗 " + e.toString(), Toast.LENGTH_LONG)
.show();
return;
}
}

// SQLiteOpenHelper#getReadableDatabase()
// で読み込み用の SQLiteDatabase# を取得
// データベースが無ければ作成して開くけども
// ここのコードではデータベースが作成されることは無い。
// それに上で 読み書き可能なインスタンスを取得しているので
// そもそもこれ自体が不要なのでコメントアウトしておく
/* mReadableDb = mHelper.getReadableDatabase() */

if (v.equals(mBtnWrite)) {
String text = mTextArea.getText().toString();
writeDb(text);
} else if (v.equals(mBtnRead)) {
loadDb();
}
}

private void writeDb(final String FIELD_VALUE) {
// ContentValuesインスタンスに
// データベースへ書き込む情報をセット
ContentValues values = new ContentValues();
values.put("ID", 1234567);
values.put("FIELD_KEY", FIELD_VALUE);

// 条件分岐 のための値を取得
String data = readDb();
if (data == null) {
// 新規書き込みはINSERT
// public long insert (String table, String nullColumnHack,
// ContentValues values)
mWritableDb.beginTransaction();

try {
mWritableDb.insert("TABLE_NAME", null, values);
mWritableDb.setTransactionSuccessful();
} finally {
mWritableDb.endTransaction();
}

Toast.makeText(this, "INSERTしました", Toast.LENGTH_LONG).show();

} else {
// すでに存在する場合はUPDATE
// public int update (String table, ContentValues values, String
// whereClause, String[] whereArgs)

mWritableDb.beginTransaction();

try {
mWritableDb.update("TABLE_NAME", values, "ID = ?",
new String[] { "1234567" });
mWritableDb.setTransactionSuccessful();
} finally {
mWritableDb.endTransaction();
}
Toast.makeText(this, "UPDATEしました", Toast.LENGTH_LONG).show();
}
}

// データベースをSELECTする関数
private String readDb() {
// SQLiteDatabase#queryメソッドで取得
// (rawQueryメソッドでも可能)
// public Cursor query (String table, String[] columns, String
// selection, String[] selectionArgs, String groupBy, String
// having,String orderBy)
// 検索結果はCursorインスタンスで返ってくる
Cursor cur = null;

try {
String groupBy = null;
String having = null;
String orderBy = null;

cur = mWritableDb.query("TABLE_NAME", new String[] { "FIELD_KEY" },
"ID = ?", new String[] { "1234567" }, groupBy, having,
orderBy);

if (cur != null && cur.moveToFirst()) {
String result = cur.getString(cur.getColumnIndex("FIELD_KEY"));
return result;
} else {
return null;
}
} finally {
if (cur != null) {
cur.close();
}
}
}

private void loadDb() {
String text = readDb();
mTextArea.setText(text);
}
}
関連があるかもしれない記事