![]()
WARNING: now that Room is out, I no longer maintain that library. If you need a library to easy access to default android ContentProvider, I would maybe suggest the use of EasyContentProviders.
AndroidQuery
AndroidQuery is an Java/Kotlin Android ORM for SQLite and ContentProvider.
While you can use other good ORMs like DbFlow/Freezer/sqlitemagic/whatever/... for your local databases, the goal of AndroidQuery is to work with several solutions/language/framework without forcing you to use one of them. For example you have:
- ContentProvider support (including some defaults models for easily accessing Android data like contacts)
- Android Loaders support (both normal and support-v4) and ContentObserver support, even without ContentProvider
- RxJava support (both version 1 and 2)
- Raw queries and custom field type support
- Kotlin support
It is also very lightweight and efficient (code generation via annotation processing).
If you want to use RxJava1 or RxJava2 you also need to add some of the following lines:
compile 'io.reactivex:rxjava:1.2.3' // For RxJava1 and rx() method
compile 'io.reactivex:rxandroid:1.2.1' // For RxJava1 and rx() method
compile 'io.reactivex.rxjava2:rxjava:2.0.2' // For RxJava2 and rx2() method
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' // For RxJava2 and rx2() method
Initialize the ORM
You need to initialize the ORM with a context to make it work properly. A good way to do it is by defining your Application object:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
Q.init(this);
}
}
And then declare it into your AndroidManifest.xml:
<application
android:name=".App">
Define your local database and models
You first need to declare your database. A BaseLocalDatabaseProvider
is using SQLite to store data.
public class LocalDatabaseProvider extends BaseLocalDatabaseProvider {
public LocalDatabaseProvider(Context context) {
super(context);
}
@Override
protected String getDbName() {
return "local_models";
}
@Override
protected int getDbVersion() {
return 1;
}
@Override
protected Resolver getResolver() {
return Q.getResolver();
}
@Override
protected void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion); // by default, AndroidQuery will create new models and add new fields
// Put here your migration code, do that directly on the db object, no AndroidQuery methods
}
@Override
protected void onPostUpgrade(int oldVersion, int newVersion) {
// Here you can directly call all kind of AndroidQuery methods, including MODEL.insert()/update()/delete()...
}
}
Then models are defined by POJOs that are annotated with @DbModel
. Model fields are annotated with @DbField
.
Java | Kotlin |
@DbModel(databaseProvider = LocalDatabaseProvider.class)
public class User {
@DbField(index = true, dbName = "_id",
primaryKey = true, autoIncrement = true)
public int id;
@DbField
public String username;
@DbField
public long timestamp;
@DbField
public boolean isRegistered;
@DbField
public byte[] profilePicture;
} | @DbModel(databaseProvider = LocalDatabaseProvider::class)
class Feed { // data class not supported
@DbField(primaryKey = true, autoIncrement = true)
var id = 0
@DbField(unique = true)
var username: String? = null
} |
Use custom types
By default AndroidQuery supports several Java/Android types, but you are not restricted to them and can define some additional types:
@TypeConverter(dbClass = String.class, modelClass = Uri.class)
public class UriConverter extends BaseTypeConverter<String, Uri> {
@Override
public String convertToDb(Uri model) {
return model == null ? null : model.toString();
}
@Override
public Uri convertFromDb(String data) {
return data == null ? null : Uri.parse(data);
}
}
Supported constraints
Here are the supported constraints:
- primary key (only on one field)
- autoincrement
- unique (both on one field or several thanks to the uniqueGroup attribute)
- not null
- foreign key