[関モバ#18] SQLBrite&SQLDelight

C49eed1cf04caeb4de645d6d9117708d?s=47 takuaraki
September 28, 2016

[関モバ#18] SQLBrite&SQLDelight

2016/09/28 関モバ#18での発表資料です。

C49eed1cf04caeb4de645d6d9117708d?s=128

takuaraki

September 28, 2016
Tweet

Transcript

  1. SQLBrite & SQLDelight 2016/09/28

  2. @ara_tack FURYU Corporation. About me

  3. Android୺຤಺ͷ σʔλϕʔε؅ཧ

  4. SQLBrite & SQLDelight

  5. SQLBrite • SQLiteOpenHelperΛϥοϓ͢Δ • ΫΤϦΛrx.Observableͱͯ͠ߪಡͰ͖Δ • ςʔϒϧมߋΛ௨஌ͯ͘͠ΕΔ

  6. SQLDelight • ςʔϒϧ࡞੒ͷSQL͔ΒϞσϧΛੜ੒͢Δ • Ϟσϧ͸JavaͷInterface • Ϟσϧ͕ܕ҆શͳಡΈ/ॻ͖ͷAPIΛఏڙ͢Δ

  7. Philosophy • SQLBrite͸௨஌ͷ࢓૊ΈΛఏڙ͢Δ͚ͩ • SQLDelight͸SQLΛ࢖͍΍͘͢͢Δ͚ͩ • SQLͷར༻Λલఏͱ͍ͯ͠Δ • ORM͡Όͳ͍

  8. Jake͸ORM͕ݏ͍ʁ ORMs are pretty much terrible on every platform. With

    undefined or ambiguous semantics around subsequent queries they are a hotspot for performance and memory problems. We'll never write an ORM. https://www.reddit.com/r/androiddev/comments/48yieg/ anyone_use_sqlbrite_andor_sqldelight/
  9. ࢖͍ํ αϯϓϧίʔυ https://github.com/takuaraki/BriteAndDelight

  10. SqlBrite sqlBrite = SqlBrite.create(); BriteDatabase db = sqlBrite.wrapDatabaseHelper(helper, Schedulers.io()); db.createQuery("users",

    "SELECT * FROM users").subscribe(new Action1() { @Override public void call(Query query) { // ॳճߪಡ࣌ͱςʔϒϧมߋ(insert,update,delete)࣌ʹݺ͹ΕΔ // query.run()Ͱ"SELECT * FROM users"ͷ࣮ߦ݁Ռ͕ಘΒΕΔ Cursor cursor = query.run(); } }); SQLBrite
  11. db.createQuery("users", "SELECT * FROM users”) .mapToList(new Func1<Cursor, User>() { @Override

    public User call(Cursor cursor) { long id = cursor.getLong(0); String name = cursor.getString(1); return new User(id, name); } }).subscribe(new Action1<List<User>>() { @Override public void call(List<User> users) { // ϢʔβʔϦετͷදࣔͳͲ } }); SQLBrite
  12. SQLDelight CREATE TABLE user (
 _id INTEGER NOT NULL PRIMARY

    KEY,
 first_name TEXT NOT NULL,
 last_name TEXT NOT NULL
 ); select_all:
 SELECT * FROM user; ྫ) User.sq
  13. User.sq → UserModel.java • ֤छఆ਺: ςʔϒϧ໊ɺΧϥϜ໊ɺSQLจ • Mapper: Cursor→ModelͷϚούʔ •

    Marshal: ContentValuesͷϏϧμʔ
  14. ֤छఆ਺ String TABLE_NAME = "user";
 
 String _ID = "_id";


    String FIRST_NAME = "first_name";
 String LAST_NAME = "last_name";
 
 String CREATE_TABLE = ""
 + "CREATE TABLE user (\n"
 + " _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n"
 + " first_name TEXT NOT NULL,\n"
 + " last_name TEXT NOT NULL\n"
 + “)"; String SELECT_ALL = ""
 + "SELECT * FROM user";
  15. Mapper final class Mapper<T extends UserModel> implements RowMapper<T> {
 private

    final Factory<T> userModelFactory;
 
 public Mapper(Factory<T> userModelFactory) {
 this.userModelFactory = userModelFactory;
 }
 
 @Override
 public T map(@NonNull Cursor cursor) {
 return userModelFactory.creator.create(
 cursor.getLong(0),
 cursor.getString(1),
 cursor.getString(2)
 );
 }
 }
  16. Marshal final class Marshal {
 protected final ContentValues contentValues =

    new ContentValues();
 
 Marshal(@Nullable UserModel copy) {
 if (copy != null) {
 this._id(copy._id());
 this.first_name(copy.first_name());
 this.last_name(copy.last_name());
 }
 }
 
 public ContentValues asContentValues() {
 return contentValues;
 }
 
 public Marshal _id(long _id) {
 contentValues.put(_ID, _id);
 return this;
 } // ҎԼলུ
 }
  17. @AutoValue
 public abstract class User implements UserModel, Parcelable { public

    static final Factory<User> FACTORY = new Factory<>(AutoValue_User::new);
 
 public static final Func1<Cursor, User> MAPPER = cursor -> new Mapper<>(FACTORY).map(cursor); 
 } Modelͷར༻
  18. // SELECT(TABLE.NAME, SELECT_ALL, MapperΛར༻) db.createQuery(User.TABLE_NAME, User.SELECT_ALL)
 .mapToList(User.MAPPER)
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(users

    -> { userAdapter.set(users); }); // INSERT(TABLE_NAME, MarshalΛར༻) db.insert(User.TABLE_NAME, User.FACTORY.marshal()
 .first_name(“taku”)
 .last_name(“araki”)
 .asContentValues()); Modelͷར༻
  19. SQLBrite & SQLDelight ͷಛ௃ • ςʔϒϧఆ͕ٛSQLͰͰ͖Δ • AutoValueͱͷ૬ੑ͕͍͍ • RxJavaͱͷ૬ੑ͕͍͍