Androidのデータ保存方法のひとつにSQLiteがある。
wikipediaより引用 SQLite はMySQLやPostgreSQLと同じデータベース管理システムであるが、サーバとしてではなくアプリケーションに組み込んで利用される軽量のデータベースである。
SQLが使えるのでそれなりに複雑なことができるし、電源を落としたからデータが消えるとかいうこともない。 消えてほしくないデータをごにょごにょするにはSQLiteがつかえる。 ちなみにiOSでも使える。
SQLiteを操作するライブラリはAndroid SDKで提供されているのでそれを使うことになる。 http://developer.android.com/reference/android/database/package-summary.html http://developer.android.com/reference/android/database/sqlite/package-summary.html
ということで、テスト的に書いてみた。
SQLitePlugin.java
[java] package tnnsst35.me.SQLiteTest;
import java.util.regex.Matcher; import java.util.regex.Pattern;
import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.content.Context;
public class SQLitePlugin { public void execute(String sql, Context ctx) { String result = ""; // Results of SQL
// SQLがなければ終了
if (sql.length() == 0) {
result = "No SQL";
return;
}
SQLiteHelper helper = new SQLiteHelper(ctx, " tnnsst35.db", 1);
SQLiteDatabase db;
// Open Database
try {
// SQLiteを書き込み可能で開く
db = helper.getWritableDatabase();
} catch (SQLiteException e) {
result = "Failed to execute SQL : " + e.getMessage();
return;
}
// SELECT文以外はexecSQLで実行できる
// 今回はINSERT, UPDATE, DELETE, CREATE, DROPで始まるSQLだけを許可するようにしている
// INSERT, UPDATE, DELETE, CREATE, DROP
if (this.isMatch(sql, "^INSERT|^UPDATE|^DELETE|^CREATE|^DROP")) {
try {
db.execSQL(sql);
result = "Success to execute SQL";
} catch (SQLiteException e) {
result = "Failed to execute SQL : " + e.getMessage();
}
}
// SELECT文はrawQueryで実行できる
// SELECT
if (this.isMatch(sql, "^SELECT")) {
try {
Cursor c = db.rawQuery(sql, null);
boolean isEof = c.moveToFirst();
result += "[";
while (isEof) {
result += "{";
for (int i = 0;i < c.getColumnCount();i++) {
if (i != 0) result += ",";
result += "\"" + c.getColumnName(i) + "\":\"" + c.getString(i) + "\"";
}
result += "}";
isEof = c.moveToNext();
if (isEof) result += ",";
}
result += "]";
c.close();
} catch (SQLiteException e) {
result = "Failed to execute SQL : " + e.getMessage();
}
}
// Close Database
db.close();
System.out.println(result);
}
private boolean isMatch(String str, String regex) {
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(str);
return m.find();
}
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context c, String dbName, int version) {
super(c, dbName, null, version);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
@Override
public void onCreate(SQLiteDatabase db) {
}
}
} [/java]
SQLiteTestActivity .java
[java] package tnnsst35.me.SQLiteTest;
import android.app.Activity; import android.os.Bundle;
import tnnsst35.me.SQLiteTest.SQLitePlugin;
public class SQLiteTestActivity extends Activity { /* Called when the activity is first created. / @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
SQLitePlugin sqlite = new SQLitePlugin();
sqlite.execute(
"CREATE TABLE IF NOT EXISTS tests (" +
"str text," +
"str2 text" +
")",
getApplicationContext()
);
sqlite.execute(
"INSERT INTO tests VALUES ('hoge', 'hoge');",
getApplicationContext()
);
sqlite.execute(
"INSERT INTO tests VALUES ('fuga', 'fuga');",
getApplicationContext()
);
sqlite.execute(
"UPDATE tests SET str2 = 'foo' WHERE str2 = 'fuga';",
getApplicationContext()
);
sqlite.execute(
"SELECT * FROM tests;",
getApplicationContext()
);
sqlite.execute(
"DROP TABLE tests;",
getApplicationContext()
);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
} [/java]
そんなにきちんと書いていないが、まぁこんなもんだと思えばよいと思う。
いちおう補足。
SELECT文の結果はJSONっぽい文字列に整形するようにしている。 例えば、今回のコードを実行すると [{"str":"hoge","str2":"hoge"},{"str":"fuga","str2":"foo"}] が標準出力される。
SQLiteDatabaseには「insert」「update」「delete」「query」などの関数が用意されていて、それを使うとSQL分を書かずにデータを操作できる。 僕は日頃からSQLを書いていて、上記の関数を使う方が面倒なので「execSQL」「rawQuery」を使うようにした。
またお気づきだとは思うが、このコードだとプレースホルダを全く使ってないのでSQLインジェクションという脆弱性を抱えている。 これについてはSQLiteStatement、SQLiteQueryBuilderとかいうそれっぽいのがあるので調べてみるとよいかと。 僕も調べます。
記事を書いといてなんだが、mucchinのAndroid戦記 - Androidアプリのデータ保存方法の一つ「SQLite」の使い方 がわかりやすいので詳しくはこちらを参照するとよいと思う。
おわり。