Room使ってみた
Room Persistence Library 使ってみた。
Room Persistence Libraryとはなんぞ
The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
https://developer.android.com/topic/libraries/architecture/room
とある。Androidのデータベースアクセスを抽象化したライブラリーっぽい。個人的にはかなり抽象化されているので作らなきゃいけないものも少し多いなっていうイメージだった。
データベースのテストを書く
今回はEntityとして、名前とid(自動インクリメント)を持つEntityをかいてみた。テストの時はinMemoryのデータベースを書いた方がいいらしい。
import android.arch.persistence.room.Room; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; @RunWith(AndroidJUnit4.class) public class SimpleEntityTest { private EntryDao mEntryDao; private AppDatabase mDb; @Before public void createDb() { Context context = InstrumentationRegistry.getTargetContext(); mDb = Room.inMemoryDatabaseBuilder(context,AppDatabase.class).build(); mEntryDao = mDb.entryDao(); } @After public void closeDb(){ mDb.close(); } @Test public void writeAndReadOneEntry(){ Entry entry = new Entry(); entry.setName("Test1"); mEntryDao.insertAll(entry); Entry gotEntry = mEntryDao.getEntryByName("Test1"); assertThat(gotEntry,equalTo(entry)); } }
Entity
EntryっていうEntityを書いた。
import android.arch.persistence.room.ColumnInfo; import android.arch.persistence.room.Entity; import android.arch.persistence.room.PrimaryKey; import java.util.Objects; @Entity(tableName = "entries") public class Entry { @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "entry_id") private long eid; @ColumnInfo(name = "name") private String name; public void setName(String name) { this.name = name; } public long getEid() { return eid; } public void setEid(long eid) { this.eid = eid; } public String getName() { return name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Entry entry = (Entry) o; return Objects.equals(name, entry.name); } @Override public int hashCode() { return Objects.hash(eid, name); } }
equalsをOverrideしないとTestのequalToで等しくならないので、nameだけ同じなら同じってことにした。primary keyのautoGenerate=trueでオートインクリメントできるらしい。
Dao
DaoはEntityのインターフェースとなる部分。ここに動作を書く。
import android.arch.persistence.room.Dao; import android.arch.persistence.room.Delete; import android.arch.persistence.room.Insert; import android.arch.persistence.room.Query; import java.util.List; @Dao public interface EntryDao { @Query("SELECT * FROM entries") List<Entry> getAll(); @Query("SELECT * FROM entries WHERE name LIKE :name LIMIT 1") Entry getEntryByName(String name); @Insert void insertAll(Entry... entries); @Delete void delete(Entry entry); }
Database
import android.arch.persistence.room.Database; import android.arch.persistence.room.RoomDatabase; @Database(entities = {Entry.class},version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract EntryDao entryDao(); }
データベース。RoomDatabaseを継承したものをつくる。
テストの実行
これでテストはパスした。
エンティティにDateの属性を付けようとしていろいろ調べたけど、jack(java android compiler kit)の警告が出たりして、時間がたりなかったのでやめた。utilのDate使うよりOffsetDateTime(jave8)を使うのがいいらしい。Dateはタイムゾーンを考慮しないので。でも、OffsetDateTimeを入れるとjackとソースコンパティビリティの警告出るんだよなぁ。build.gradleでjack enabled=trueを入れてcompileOptionを消せばいいんだけどなんだかなぁという感じだった(加藤恵)。あとでちゃんとやってみたい。