Androidでは、SQLiteというデータベースが標準でサポートされています。
SQLiteを使うには、android.database.sqliteパッケージのSQLiteDatabase, SQLiteOpenHelper, SQLiteStatementあたりのクラスを使ってゴリゴリSQLを書くわけです。
SQLiteを使うコードの例
public List<Account> getAllAccounts() {
SQLiteDatabase database = dbHelper.getWritableDatabase();
List<Account> accounts = new ArrayList<Account>();
Cursor cursor = database.query("accounts",
{"id","name","mail"}, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Account account = new Account();
account.setId(cursor.getLong(0));
account.setName(cursor.getString(1));
account.setMail(cursor.getString(2));
accounts.add(account);
cursor.moveToNext();
}
cursor.close();
return accounts;
}
フィールド名の文字列やマッピングがコードに埋め込まれ、マジックナンバーになっています。これが問題になることがあります。
- SQLの構文が正しいか実行するまでわからない。
- SQLの構文が正しくても、スキーマとオブジェクトが意図通りマッピングされているか、実行するまでわからない。
- SQL文でコードの見通しが悪くなる。
- スキーマを共有するのが面倒。
- ビジネスロジック以外のコードが増える。
- スキーマ変更にメッチャ弱い。
他にもあると思います。
この問題を放置すると、気づかないうちに徐々に開発のペースを奪われます。リリース後では、機能追加や修正が困難な状態になっていることもあります。
ようするに「アプリの本質的なロジックだけに集中して開発できればいい」わけです。
ORMLiteは、これらの問題を解決するのに役立ちます。ORMLiteは、データベースの読み書きをするためのORM(Object Relational Mapper)です。
ORMLiteをダウンロードしてビルドパスを通す
必要なライブラリ
DatabaseHelperを作成する
DatabaseHelper.java
package com.luckyandhappy.models;
import java.sql.SQLException;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// SDCardのディレクトリを指定
private static final String DATABASE_NAME = Environment.getExternalStorageDirectory() + "/Sample.db";
private static final int DATABASE_VERSION = 1;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase arg0, ConnectionSource arg1) {
try {
TableUtils.createTable(arg1, Account.class);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "データベースを作成できませんでした", e);
}
}
@Override
public void onUpgrade(SQLiteDatabase arg0, ConnectionSource arg1, int arg2,
int arg3) {
}
}
エンティティを作成する
Account.java
package com.luckyandhappy.models;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "accounts")
public class Account {
@DatabaseField(generatedId = true)
private Integer id;
@DatabaseField
private String name;
@DatabaseField(canBeNull = true)
private String mail;
public Account() {}
public Account(String name) {
this.name = name;
}
public Account(String name, String mail) {
this.name = name; this.mail = mail;
}
public Integer getId() { return this.id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public String getMail() { return this.mail; }
public void setMail(String mail) { this.mail = mail; }
}
モデルを作成する
AccountModel.java
package com.luckyandhappy.models;
import java.util.List;
import android.content.Context;
import android.util.Log;
import com.j256.ormlite.dao.Dao;
public class AccountModel {
private static final String TAG = AccountModel.class.getSimpleName();
private Context context;
public AccountModel(Context context) {
this.context = context;
}
public void save(Account account) {
DatabaseHelper helper = new DatabaseHelper(context);
try {
Dao<Account, Integer> dao = helper.getDao(Account.class);
dao.createOrUpdate(account);
} catch (Exception e) {
Log.e(TAG, "例外が発生しました", e);
} finally {
helper.close();
}
}
public List<Account> findAll() {
DatabaseHelper helper = new DatabaseHelper(context);
try {
Dao<Account, Integer> dao = helper.getDao(Account.class);
return dao.queryForAll();
} catch (Exception e) {
Log.e(TAG, "例外が発生しました", e);
return null;
} finally {
helper.close();
}
}
}
モデルを操作するアクティビティを作成する
ORMLiteExampleActivity.java
package com.luckyandhappy;
import com.luckyandhappy.models.Account;
import com.luckyandhappy.models.AccountModel;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class ORMLiteExampleActivity extends Activity {
private static final String TAG = ORMLiteExampleActivity.class.getSimpleName();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Account miku = new Account("初音ミク", "miku@vocaloid.net");
Account rin = new Account("鏡音リン", "rin@vocaloid.net");
Account len = new Account("鏡音レン", "len@vocaloid.net");
Account ruka = new Account("巡音ルカ", "luka@vocaloid.net");
AccountModel model = new AccountModel(this);
model.save(miku);
model.save(rin);
model.save(len);
model.save(ruka);
for(Account account : model.findAll()) {
Log.d(TAG, String.format("id=%s,name=%s,mail=%s",
account.getId(),account.getName(),account.getMail()));
}
}
}
AndroidManifest.xmlを設定する
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.luckyandhappy"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ActiveAndroidExampleActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
実行結果
どんなデータベースができているでしょうか。SQLite Database Browserを使って確認してみます。
SQLiteのデータベースはひとつのファイルになっています。SDCard内のSample.dbを開きます。
accountsテーブルのスキーマです。
accountsテーブルのレコードです。きちんと登録されているのがわかります。