Slide 1

Slide 1 text

How to select ORM? @hotchemi

Slide 2

Slide 2 text

Agenda 1. Who am I? 2. How to select ORM? 3. ActiveAndroid 4. DBFlow 5. Conclusion

Slide 3

Slide 3 text

1 Who am I?

Slide 4

Slide 4 text

Who am I? • Name: Shintaro Katafuchi • GitHub, Twitter: @hotchemi • Library: Android-Rate https:/github.com/hotchemi/Android-Rate • From Japan, just sightseeing! • Member of DroidKaigi

Slide 5

Slide 5 text

DroidKaigi?

Slide 6

Slide 6 text

• Held in Tokyo 025/04/2015 • Over 400 participants • 22 session • http://droidkaigi.github.io • We’re planning Droidcon Tokyo… DroidKaigi

Slide 7

Slide 7 text

2 How to select ORM?

Slide 8

Slide 8 text

03.-JUF HSFFO%"0 0MMJF "DUJWF"OESPJE 4VHBS03. 3FBMN DPVDICBTFMJUF TQSJOLMFT TDIFNBUJD

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

How to select ORM? 1. Easy to use 2. Kind documentation and support 3. Well known or not 4. Active development 5. Good performance

Slide 11

Slide 11 text

3 ActiveAndroid

Slide 12

Slide 12 text

The good parts • Pretty popular(★2383 in GitHub) • Quite easy to use • Enough documentation and information • Using with ContentProvider

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Save and delete Category restaurants = new Category(); restaurants.name = "Restaurants"; restaurants.save(); restaurants.delete();

Slide 15

Slide 15 text

Select List items = new Select().from(Item.class).where("age > ?", 0).execute();

Slide 16

Slide 16 text

The bad parts • Migration isn’t type safe • Difficulty with complex join • Using a lot of reflection • The performance is not so high • Development isn’t active… • Because of Ollie? It isn’t active neither :)

Slide 17

Slide 17 text

Complex join final From query = new Select("Genres.genre_id", "Genres.name as genreName", "Genres.category_id", "Categories.name as categoryName") .from(Genre.class) .innerJoin(Category.class) .on("Genres.category_id = Categories.category_id") .where("Genres.active = 1 and Categories.active = 1") .orderBy("Categories.sort, Genres.sort"); final Cursor cursor = Cache.openDatabase().rawQuery(query.toSql(), query.getArguments());

Slide 18

Slide 18 text

Migration ALTER TABLE Items ADD COLUMN color INTEGER; ALTER TABLE Items ADD COLUMN name TEXT; ALTER TABLE Items ADD COLUMN kind TEXT; BTTFUTNJHSBUJPOT/FX7FSTJPOTRM

Slide 19

Slide 19 text

4 DBFlow

Slide 20

Slide 20 text

The good parts • Enough popular(★761 in GitHub) • Fullset API(ModelView, observable, multiple database) • Enough documentation • Active development • The performance is higher than ActiveAndroid • Using APT

Slide 21

Slide 21 text

Performance IUUQXXXSBJ[MBCTDPNEFWHPECqPXGBTUFTUBOESPJEPSNEBUBCBTFMJCSBSZ

Slide 22

Slide 22 text

Initialize @Database(name = AppDatabase.NAME, version = AppDatabase.VERSION) public class AppDatabase { public static final String NAME = "App"; public static final int VERSION = 1; } @Table(databaseName = AppDatabase.NAME) public class TestModel1 extends BaseModel { @Column(columnType = Column.PRIMARY_KEY) public String name; }

Slide 23

Slide 23 text

Category restaurants = new Category(); restaurants.name = "Restaurants"; restaurants.save(false); // async or not restaurants.delete(false); Save and delete

Slide 24

Slide 24 text

List devices = new Select().from(DeviceObject.class) .where( Condition.column(DeviceObject$Table.NAME).is("Samsung-Galaxy-S5"), Condition.column(DeviceObject$Table.CARRIER).is("T- Mobile")).queryList(); Select

Slide 25

Slide 25 text

ModelView @ModelView(query = "SELECT time from AModel where time > 0", databaseName = AppDatabase.NAME) public class AModelView extends BaseModelView { @Column long time; }

Slide 26

Slide 26 text

Migration @Migration(version = 2, databaseName = TestDatabase.NAME) public class Migration1 extends BaseMigration { @Override public void onPreMigrate() { // called before migration, instantiate any migration query here } @Override public void migrate(SQLiteDatabase database) { // call your migration query } @Override public void onPostMigrate() { // release migration resources here } }

Slide 27

Slide 27 text

Observable FlowContentObserver.ModelChangeListener modelChangeListener = new FlowContentObserver.ModelChangeListener() { @Override public void onModelChanged() { // called in SDK<14 } @Override public void onModelSaved() { } @Override public void onModelDeleted() { } @Override public void onModelInserted() { } @Override public void onModelUpdated() { } };

Slide 28

Slide 28 text

Observable observer.addModelChangeListener(modelChangeListener); TestNotifiableModel testModel = new TestNotifiableModel(); testModel.setName("myName"); // will notify our observer automatically, no configuration needed! testModel.insert(async); testModel.update(async); testModel.save(async); testModel.delete(async); // when done with listener observer.removeModelChangeListener(modelChangeListener);

Slide 29

Slide 29 text

The bad parts • Too early? • Too many functions • Content Provider Generation • Triggers, Indexes • Model Containers • Other than that…a lot!

Slide 30

Slide 30 text

5 Conclusion

Slide 31

Slide 31 text

Comparison ActiveAndroid DBFlow Easy ̋ △ Popular ◎ ̋ Active development △ ̋ Documentation ̋ ̋ Perfomance ̋ ◎ Migration ☓ ̋ Function △ ◎ Simple ◎ ̋

Slide 32

Slide 32 text

Conclusion • If you want to use a simple API, • →ActiveAndroid • If you want to see other’s sample or blog, • →ActiveAndroid • If you have to take care of performance, • →DBFlow • If you have to use multiple database, • →DBFlow

Slide 33

Slide 33 text

Other than that? • ORMLite…Looks good to me but not simple. • GreenDAO…Performance is awesome but it’s annoying to write dao generation code. • SugarORM…It seems have good performance than AA but…not popular. • Realm…The highest performance, but not SqLite, bad migration, we can only write setter/getter to Model. • Other than that I’m not sure…

Slide 34

Slide 34 text

It depends! Thank you!