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.
Project stORM:
an ORM for SQLite
+David Chandler
(ex) Android Developer Advocate
http://turbomanage.com
simple
template-based
Object
Relational
Mapping
David Chandler
turbomanage.wordpress.com
1.0
why
hand-coded SQL, ugh
why
SQLite already has obj-like wrappers
- ContentValues (insert, update)
- Cursor (query)
many apps just require a place ...
goals
easy
convention over configuration
annotation-driven
- @Database, @Entity
- seamless code gen with JDT
easy to debug
...
non-goals
kitchen sink
model all relations
absolute max performance
setup (Eclipse / ADT)
add storm-api.jar to libs/
add storm-impl.jar to annotation factory
classpath
setup (Android Studio)
github.com/turbomanage/storm-gen
buildscript {
repositories {
mavenCentral()
}
dependencies {
class...
use
Extend DatabaseHelper, annotate with
@Database
Create POJOs, annotate with @Entity
Generates
- DbFactory
- EntityTable...
use (like Objectify)
dao.insert(T obj)
dao.insertMany(Iterable<T> objs)
T dao.get(long id)
dao.update(T obj)
dao.delete(lo...
conventions
generated package names
- +.db, +.dao
COLNAME ==
fieldName.toUpperCase()
transient fields are not persisted
id
-...
supported types
all primitives & wrappers
- boolean, byte, byte[], char, double, enum,
float, int, long, short, String
- by...
nice
List<T> dao.listByExample(T obj)
T dao.getByExample(T obj)
- throws TooManyResultsException
insertMany uses 1 transac...
csv
dao.getDatabaseHelper(ctx)
dbHelper.backupAllTablesToCsv()
dbHelper.restore...FromCsv()
exact type conversions
- blobs...
UpgradeStrategy
DROP_CREATE
BACKUP_RESTORE (csv)
- dropped cols disappear
- new cols get default values
- renaming not yet...
limits
no relations (yet)
- want: order.items
- have: item.orderId
- could: orderDao.getItems()
- leaning toward Ref<Order...
sqlite3
adb shell
cd /data/data/your_app/databases
sqlite3 name_of_db
.schema
SELECT * FROM ...
dbFactory
static db name, version
singleton instance of DatabaseHelper
getTableHelpers()
dao
extends SQLiteDao<T>
- most of the code lives in the base class
points to DatabaseFactory
points to TableHelper
table
all SQL
all getX() / bindX()
Cursor --> obj --> ContentValues
obj --> String[] (for csv)
impl
how to support incremental
compilation?
- anno processing happens in rounds
- full src not available in every round
-...
working with APT
Start gradle daemon
Connect a remote debugger to it
Initiate your build (including APT
processing)
In Int...
Android Debug Bridge
adb logcat
adb shell
adb shell dumpsys meminfo <pkg>
adb kill-server :-(
other command lines
- androi...
Freebie: adb back up
adb backup -apk -all -nosystem -f
~/mybackupfile.ab
adb restore ~/mybackupfile.ab
future
limited relations (@Key, Ref<T>)
more filter methods gt(), lt(), etc.
@Id for custom id col
@Column(name=”custom”)
src
github.com/turbomanage/storm-gen
R
androidannotations.org
Mark Murphy’s Busy Coder’s Guide to
Android Development
Google I/O sessions
+Android Developers
t...
Upcoming SlideShare
Loading in …5
×

StORM: a lightweight ORM for Android SQLite

698 views

Published on

Android’s bundled SQLite database is powerful, but requires a lot of hand-coded SQL to get started. Using an ORM can simplify database development for many applications, and the Android ecosystem already has several to choose from. stORM is a lightweight DAO generator that aims for a streamlined developer experience (only two annotations required) and solid performance (preferring code generation over reflection). stORM is extensible, minimally intrusive, and offers built-in CSV backup / restore capabilities to facilitate database version upgrades. Along with stORM itself, Chandler presents techniques for writing and debugging an Android annotation processor that can be used with Eclipse, IntelliJ, or Android Studio.

Published in: Software
  • Be the first to comment

StORM: a lightweight ORM for Android SQLite

  1. 1. Project stORM: an ORM for SQLite +David Chandler (ex) Android Developer Advocate http://turbomanage.com
  2. 2. simple template-based Object Relational Mapping David Chandler turbomanage.wordpress.com 1.0
  3. 3. why hand-coded SQL, ugh
  4. 4. why SQLite already has obj-like wrappers - ContentValues (insert, update) - Cursor (query) many apps just require a place to stuff some objects existing ORMs use reflection or require up-front modeling
  5. 5. goals easy convention over configuration annotation-driven - @Database, @Entity - seamless code gen with JDT easy to debug minimal performance overhead
  6. 6. non-goals kitchen sink model all relations absolute max performance
  7. 7. setup (Eclipse / ADT) add storm-api.jar to libs/ add storm-impl.jar to annotation factory classpath
  8. 8. setup (Android Studio) github.com/turbomanage/storm-gen buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.13.+' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } } apply plugin: 'android-apt' dependencies { apt ‘com.turbomanage.storm:storm-impl:1.0' compile 'com.android.support:appcompat-v7:19.1.0' compile 'log4j:log4j:1.2.17' compile 'javax.persistence:persistence-api:1.0' compile ‘com.turbomanage.storm:storm-api:1.0' }
  9. 9. use Extend DatabaseHelper, annotate with @Database Create POJOs, annotate with @Entity Generates - DbFactory - EntityTable - EntityDao new EntityDao(ctx).insert/get/query...
  10. 10. use (like Objectify) dao.insert(T obj) dao.insertMany(Iterable<T> objs) T dao.get(long id) dao.update(T obj) dao.delete(long id) / dao.deleteAll() List<T> dao.listAll() or load().list() dao.listAllByExample(T exampleObj) dao.load().eq(COL, val).eq(...).exec()
  11. 11. conventions generated package names - +.db, +.dao COLNAME == fieldName.toUpperCase() transient fields are not persisted id - long id (default) - or annotate another field with @Id - column name is _id (for CursorAdapter)
  12. 12. supported types all primitives & wrappers - boolean, byte, byte[], char, double, enum, float, int, long, short, String - byte[] have affinity BLOB - boolean, byte, char have affinity INTEGER roll-your-own - extend TypeConverter<J,S> - annotate with @Converter
  13. 13. nice List<T> dao.listByExample(T obj) T dao.getByExample(T obj) - throws TooManyResultsException insertMany uses 1 transaction column name enum in Table class - filter().eq(Columns.FIRSTNAME, “David”)... red squigglies from APT
  14. 14. csv dao.getDatabaseHelper(ctx) dbHelper.backupAllTablesToCsv() dbHelper.restore...FromCsv() exact type conversions - blobs are Base64 encoded - doubles saved as raw hex values file named dbName.vn.TableName+?
  15. 15. UpgradeStrategy DROP_CREATE BACKUP_RESTORE (csv) - dropped cols disappear - new cols get default values - renaming not yet supported UPGRADE - override DatabaseHelper.upgrade() and/or - override TableHelper.onUpgrade(...) for each
  16. 16. limits no relations (yet) - want: order.items - have: item.orderId - could: orderDao.getItems() - leaning toward Ref<Order>.get() can’t compare doubles or blobs with FilterBuilder.eq() - planned: .eq(COL, val, delta) - alt: dao.query(String where, String[] args)
  17. 17. sqlite3 adb shell cd /data/data/your_app/databases sqlite3 name_of_db .schema SELECT * FROM ...
  18. 18. dbFactory static db name, version singleton instance of DatabaseHelper getTableHelpers()
  19. 19. dao extends SQLiteDao<T> - most of the code lives in the base class points to DatabaseFactory points to TableHelper
  20. 20. table all SQL all getX() / bindX() Cursor --> obj --> ContentValues obj --> String[] (for csv)
  21. 21. impl how to support incremental compilation? - anno processing happens in rounds - full src not available in every round - stormEnv file under .apt_generated (ADT) - or build/generated/apt/debug (AS) - if in doubt, del stormEnv & Project | Clean Freemarker templates in impl/src/res watch the Error Log view
  22. 22. working with APT Start gradle daemon Connect a remote debugger to it Initiate your build (including APT processing) In IntelliJ, use Rebuild to force APT run http://turbomanage.wordpress.com/ 2014/06/09/debug-an-annotation- processor-with-intellij-and-gradle/
  23. 23. Android Debug Bridge adb logcat adb shell adb shell dumpsys meminfo <pkg> adb kill-server :-( other command lines - android (launches SDK manager) - hierarchyviewer - emulator @avd_name (see ~/.android/avd)
  24. 24. Freebie: adb back up adb backup -apk -all -nosystem -f ~/mybackupfile.ab adb restore ~/mybackupfile.ab
  25. 25. future limited relations (@Key, Ref<T>) more filter methods gt(), lt(), etc. @Id for custom id col @Column(name=”custom”)
  26. 26. src github.com/turbomanage/storm-gen
  27. 27. R androidannotations.org Mark Murphy’s Busy Coder’s Guide to Android Development Google I/O sessions +Android Developers turbomanage.com (my blog) google.com/+DavidMichaelChandler square.github.com (event bus, DI, etc.)

×