Edited at

ActiveAndroidのWikiを和訳した

More than 3 years have passed since last update.

ActiveAndroidとは、アクティブ・レコードパターンのAndroidのORMです。

結構好きなので公式Wikiを和訳しました。


Getting started


Adding the JAR

jarを取得してプロジェクトにビルドパスを通す。


  1. ソースをcloneしてルートフォルダでantコマンドを実行する。成果物はdistフォルダに作成される。

  2. Downloadsから最新のjarをダウンロードしてくる


Installing from Maven

Gitからソースをcloneしてローカルのmavenリポジトリにインストールする。


  1. git clone https://github.com/pardom/ActiveAndroid.git

  2. cd ActiveAndroid

  3. mvn clean install

pomにdependencyを追加。

<dependency>

<groupId>com.activeandroid</groupId>
<artifactId>activeandroid</artifactId>
<version>(insert latest version)</version>
</dependency>


Configuring your project

ActiveAndroidをアプリケーションで使用する為には、AndroidManifest.xmlに設定を追加する。

下記オプションを追加する。


  • AA_DB_NAME

  • AA_DB_VERSION(デフォルトは1)

<manifest>

<application android:name="com.activeandroid.app.Application" ...>
...
<meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" />
<meta-data android:name="AA_DB_VERSION" android:value="5" />

</application>
</manifest>

もしくは、コード内で指定する事も可能である。

public class MyApplication extends Application {

@Override
public void onCreate() {
super.onCreate();
Builder builder = new Configuration.Builder(getBaseContext());
builder.setDatabaseName("test.db");
builder.setDatabaseVersion(1);
ActiveAndroid.initialize(builder.create());
}

@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}

ActiveAndroidを使用する為には、アプリケーションのエンドポイントをActiveAndroidのApplicationクラスにする事。

既に独自のApplicationクラスを作成していた場合は、com.activeandroid.app.Applicationを継承するかinitializeメソッドとdisposeメソッドをコールする事。

public class MyApplication extends com.activeandroid.app.Application { ...

public class MyApplication extends SomeLibraryApplication {

@Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
}
@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}
}


Creating your database model

データベースモデルの作成は簡単です。プロパティのアノテーションの引数に対応するカラム名が作成されます。

モデルを作成する為には、クラスがModelクラスを継承する必要がある事と、クラスに@Tableアノテーション、メンバに@Columnアノテーションを付与する必要がある事を覚えておいてください。

各アノテーションのオプションは下記の様になります。

定義先
定義内容
意味

@Table
name
対応するテーブル名

@Column
name
対応するカラム名

length
長さの制約(デフォルト -1(無制限?))

notNull
not null制約(デフォルト false)

onNullConflict
null制約違反時の動作を設定する(デフォルトはFAIL, 設定内容はAndroid公式参照)

onDelete
削除時の外部キーの動作設定(CASCADE, RESTRICT等が設定可能)

onUpdate
更新時の外部キーの動作設定(CASCADE, RESTRICT等が設定可能)

unique
ユニーク制約(デフォルト false)

onUniqueConflict
ユニーク制約違反時の動作を設定\n(デフォルトはFAIL, 設定内容はAndroid公式参照)


コンストラクタ

ActiveAndroidは、オブジェクトをインスタンス化する際の標準的なコンストラクタを使用しています。

@Table(name = "Items")

public class Item extends Model {
@Column(name = "Name")
public String name;
@Column(name = "Category")
public Category category;

public Item(){
super();
}
public Item(String name, Category category){
super();
this.name = name;
this.category = category;
}
}


Relationships

ActiveAndroidではどの様にしてリレーションを実現するのでしょうか?

Itemクラスではメンバに直接Categoryを追加します。

@Table(name = "Items")

public class Item extends Model {
@Column(name = "Name")
public String name;

@Column(name = "Category")
public Category category;
}

CategoryクラスではヘルパーメソッドのgetManyを使用して1対多のリレーションを実現します。

@Table(name = "Categories")

public class Category extends Model {
@Column(name = "Name")
public String name;

public List<Item> items() {
return getMany(Item.class, "Category");
}
}


Saving to the database


挿入と更新

Category restaurants = new Category();

restaurants.name = "Restaurants";
restaurants.save();

リレーションがある場合

Item item = new Item();

item.category = restaurants;
item.name = "Outback Steakhouse";
item.save();


Bulk insert

約100倍に高速化できるとの事。

ActiveAndroid.beginTransaction();

try {
for (int i = 0; i < 100; i++) {
Item item = new Item();
item.name = "Example " + i;
item.save();
}
ActiveAndroid.setTransactionSuccessful();
}
finally {
ActiveAndroid.endTransaction();
}


Deleting records

3種類の方法を提供しています。

Item item = Item.load(Item.class, 1);

item.delete();

Item.delete(Item.class, 1);

new Delete().from(Item.class).where("Id = ?", 1).execute();


Querying the database

ActiveAndroidのクエリはBuilderパターンかModel#queryメソッドを使用して構築されます。

Itemモデルを例に考えてみましょう。

@Table(name = "Items")

public class Item extends Model {
@Column(name = "Name")
public String name;

@Column(name = "Category")
public Category category;
}

Itemから1件ランダムに取得したい場合は下記の様に記述します。

public static Item getRandom() {

return new Select().from(Item.class).orderBy("RANDOM()").executeSingle();
}

カテゴリに紐づくItem1件を取得したい場合は下記の様に記述します。

public static Item getRandom(Category category) {

return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("RANDOM()")
.executeSingle();
}

カテゴリに紐づく全てのアイテムを取得したい場合は下記の様に記述します。

public static List<Item> getAll(Category category) {

return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("Name ASC")
.execute();
.executeSingle();
}


Type serializers

ActiveAndroidはデフォルトで様々なクラスをサポートしていますが、サポート外のオブジェクトを扱う場合はTypeSerializerクラスを拡張したクラスを作成します。

TypeSerializerクラスを扱う上でベストな方法はソースコードを読む事です!ここではDate型を考えてみましょう。

TypeSerializerを作成する時に考える事は、いかにしてオブジェクトをActiveAndroidがサポートしている基本型に落としこむかという事です。

DateはLong型に変換できるので、Long型を使用してみましょう。

final public class UtilDateSerializer extends TypeSerializer {

@Override
public Class<?> getDeserializedType() {
return Date.class;
}

@Override
public Class<?> getSerializedType() {
return Long.class;
}

@Override
public Long serialize(Object data) {
if (data == null) {
return null;
}

return ((Date) data).getTime();
}

@Override
public Date deserialize(Object data) {
if (data == null) {
return null;
}

return new Date((Long) data);
}
}

まず、getDeserializedType を確認します。このメソッドではシリアライズしようとしているクラスのクラスオブジェクトを返却します。

Date型の場合はDate.classを返却します。

次のメソッド(getSerializedType)は逆の、つまり我々がデータベースに格納したい型を確認します。リテラル型が返却される事を期待するよりもむしろ、enumを選択してください。

このメソッドでは下記のenumを使用する事ができます。

public enum SQLiteType {

INTEGER, REAL, TEXT, BLOB
}

次のメソッド(serialize)でActiveAndroidがサポートしている型に変換を行います。ここではDate型をLong型にキャストする為にgetDateメソッドを使用しています。

最後のメソッド(serialize)ではデータベースのデータを我々が期待する型に変換します。ここではLong型からDate型へのキャストを実施しています。

あなたが作成したTypeSerializerを使用する為には、AndroidManifest.xmlで宣言する必要があります。

<meta-data android:name="AA_SERIALIZERS" 

android:value="my.package.CustomTypeSerializer,my.package.AnotherCustomeTypeSerializer" />


Using the content provider

bq. このコードを動作させる際は、ここで指定したデフォルトのID列をオーバーライドする必要があります。

mySpinner.setAdapter(new SimpleCursorAdapter(getActivity(),

android.R.layout.simple_expandable_list_item_1,
null,
new String[] { "MyProperty" },
new int[] { android.R.id.text1 },
0));

getActivity().getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle cursor) {
return new CursorLoader(getActivity(),
ContentProvider.createUri(MyEntityClass.class, null),
null, null, null, null
);
}

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> arg0) {
((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(null);
}
});


Schema migrations

新しいクラスが追加された際、ActiveAndroidはデフォルトでデータベースにテーブルを追加します。

既存のテーブルに変更を加える際には、assets/migrationsに配置したsqlスクリプトを実行する事で実現します。


手順


  1. ConfigurationクラスかAndroidManifest.xmlのAA_DB_VERSIONをインクリメントします。

  2. .sqlを/assets/migrationsに配置します。

ActiveAndoridは既存のDBバージョン番号から新しいバージョン番号までの範囲の数字と一致するファイル名のSQLを順番に実行します。

例えば、Itemsテーブルにcolor カラムを追加する場合には、AA_DB_VERSIONを2にインクリメントして2.sqlというファイルを配置します。

ALTER TABLE Items ADD COLUMN Color INTEGER;


Pre populated databases

事前データを準備したい場合はassetsディレクトリにコピーを追加します。

データベースが正しくAndroid上で動作している事を確認するには次のステップを踏みます。



  1. android_metadataをセットアップします。

  2. 全てのプライマリキーフィールドの名前をIdという名前に変更します(標準のAndroidデータベースと同様に_idではなく)


Shipping with a database

coming soon…