Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Green dao


Published on

Published in: Technology, Education

Green dao

  1. 1. A look behind the scenes greenDAODroidcon Berlin 2012,Markus Junginger
  2. 2. About me, Follow me Android developer since 2007 Founder of, Munich @green_dao Most updates  @greenrobot_de Most important updates  +Markus Junginger  +greenrobot 
  3. 3. Agenda What is greenDAO? – SQLite database – ORM – Code generation based on meta model Background info and „secret“ internals – Why code generation? – Performance Tweaks
  4. 4. Problem with DB Development Database world  ||  Java world No object orientation Data access feels quite low levely A lot of boilerplate code for SQLite – SQL scripts, e.g.: CREATE TABLE, Queries – Cursor iterations – Parameter binding
  5. 5. Common solution: ORM Java Object SQLite greenDAO Java Object Database Java Object ORM offers a higher level API – Read and write objects – CREATE TABLE done for you – Expressing Queries
  6. 6. Example: SQLite vs. greenDAOString[] columns = { "note", "date_changed" };String[] idArgs = { String.valueOf(id) };SQLiteCursor cursor = (SQLiteCursor) db.query("notes", columns,"_id=?", idArgs, null, null, "note");try { // greenDAO if (cursor.getCount() != 1) { Note note = noteDao.load(id); throw new Exception("Unexpected count: " +cursor.getCount()); updateUi(note.getNote(), note.getDate()); } cursor.moveToNext(); String note = cursor.getString(0); String date = cursor.getString(1); updateUi(note, date);} finally { cursor.close();}
  7. 7. greenDAO Overview Entities & DAOs Code generation Open Source: Apache 2 license: core library (embedded in your app) GPL3: generator (you usually don‘t have changes here)
  8. 8. greenDAO StructureGenerator Project Android Project (Plain Java) Sources Schema-Model • Entities • Properties Generated • Relations Sources greenDAO Code Generation • Indexes, … • Entities • DAOs greenDAO Generator Lib greenDAO +FreeMarker Core Lib
  9. 9. Code Generation: Meta Model In generator project Defines data model (your schema) Define with Java
  10. 10. Example: Model for GeneratorSchema schema = new Schema(1, "de.greenrobot.daoexample");Entity simple = schema.addEntity("Note");simple.addIdProperty();simple.addStringProperty("text").notNull();simple.addDateProperty("date");new DaoGenerator().generateAll( "../DaoExample/src-gen", schema);
  11. 11. Example: Generated Entitypublic class Note { private String text; // ID, date and constructors skipped public String getText() { return text; } public void setText(String text) { this.text = text; }}
  12. 12. Code: Insert, Update, DeleteNote note = new Note();note.setText(“Say hello to world”);noteDao.insert(note);Log.d("Dao", “New ID: " + note.getId());note.setText(“Save the world”);noteDao.update(note);noteDao.delete(note);
  13. 13. QueryBuilder References generated Properties Java Complier checks Example: Get all users with first name “Joe“, and sort by last name List<User> joes = userDao.queryBuilder() .where(Properties.FirstName.eq("Joe")) .orderAsc(Properties.LastName) .list();
  14. 14. Entity relations Entity type relates to another entity type Supports to-one and to-many relations Unidirectional Bidirectional: requires manual updates
  15. 15. ToOne Example Entities Customer & Order An order has one customer Modelling in the generator project Property customerId = order.addLongProperty( "customerId").notNull().getProperty(); order.addToOne(customer, customerId); Resolving in the app Customer customer = order.getCostumer();
  16. 16. ToMany Example Entities Customer & Order A customer places many orders Modelling in the generator project Property customerId = order.addLongProperty( "customerId").notNull().getProperty(); customer.addToMany(order, customerId); Resolving in the app List<Order> orders = costumer.getOrderList();
  17. 17. Active Entities Have (some) persistence methods – update – delete – refresh
  18. 18. greenDAO Design Goals Maximum Performance Low resource usage – Memory consumption – Library size Easy-to-use API Focus on the essentials Optimized for Android
  19. 19. Save size, keep it the DRY way Generate code, but as sparly as possible Example: load method of DAO AbstractDao class (core library) – Implements everything expect readEntity Generated DAO implements readEntity – Just construct entities from a cursor position Library size: 59 KByte + some K per DAO
  20. 20. 3 Basic Performance Rules1. Group DB changes into a transaction! Can be like 500 times faster; still a FAQ2. Don’t forget database indexes3. Use prepared statements (precompiled)
  21. 21. Regular Performance Tracking Different scenarios are tested Tracked in Excel files Excel files are pushed to github
  22. 22. Why Code Generation? Annotation-based solutions: common with JEE ORMs (Hibernate, JPA) Parsing of annotations  start-up time Android & annotations: getting/setting values requires reflection Reflection quite slow on Android (n. slide) Code generation to avoid reflection
  23. 23. Reflection PerformanceMethod Reflection (roughly)getInt ~ 50 x slowergetString ~ 50 x slowersetInt ~ 400 x slowersetString ~ 150 x slower Example: 100,000 Operations (e.g. 10,000 entities with 10 properties) setInt: 9 ms, reflected 3875ms
  24. 24. Profiling to find hotspots Use traceview Enable in code: Debug. startMethodTracing( traceName); See class PerformanceTest
  25. 25. Reading entities & Constructor Entities read from the database Solution 1: Calling setters MyEntity myEntity = new MyEntity(); myEntity.setX(cursor.getString(0)); … Solution 2: Constructor only MyEntity myEntity = new MyEntity( cursor.getString(0), …); Performance gain: 33%
  26. 26. Optimization Candidate: Cursor Quite some time is spent in Android API android.database.AbstractWindowedCursor get… Methods are “slow” @Override public short getShort(int columnIndex) { checkPosition(); return mWindow.getShort(mPos, columnIndex); } @Override public int getInt(int columnIndex) { checkPosition(); return mWindow.getInt(mPos, columnIndex); }
  27. 27. Custom Cursor implementation Replacing SQLiteCursor de.greenrobot.dao.FastCursor Performance gain: ~30%
  28. 28. Lookup by ID Identity Scope (≈ Entity Caching) Mapping ID  Entity HashMap<Long, MyEntity> Problem: Long object creation LongSparseArray<MyEntity> Problem: does not scale Evaluated several alternatives
  29. 29. LongHashMap & More Custom de.greenrobot.dao.LongHashMap + Locking improvements + Minor performance tweaks Performance gain: from 30% up to 117%
  30. 30. Performance: Entities / SecondMeasured on a Nexus S (1 GHz), Android 2.3
  31. 31. Performance comparisonMeasured on a Nexus S (1 GHz), Android 2.3
  32. 32. Current Workflow vs. Migration Works best if you start from scratch (Start with Entity modeling) Migration: additional effort required – Pre-existing entities: have to be replaced – Existing tables: entities have to modeled Ideas how to address migration – Generic DAO (Annotation based entities!) – Import existing Model from SQLite DB files
  33. 33. Current Feature Requests Generate Adapters, CRUD Apps, Parceable, conversion to JSON/XML, … Convenience support for async ops Client/Server(Cloud) data synchronization More flexible primary keys (PKs) Pre- and post persist callbacks What is most important to you?
  34. 34. Disclaimer, Rechtliches Alle Inhalte urheberrechtlich geschützt. © Copyright 2011 Markus Junginger All rights reserved. Kontakt:!/greenrobot_de