v1.4.1 (Jan 13, 2017)
Nov 6, 2016
Jul 31, 2017 (Retired)
Frédéric Julian (FredJul)
Frédéric Julian (FredJul)
Source code


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 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 {

    public void onCreate() {


And then declare it into your AndroidManifest.xml:


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) {

    protected String getDbName() {
        return "local_models";

    protected int getDbVersion() {
        return 1;

    protected Resolver getResolver() {
        return Q.getResolver();

    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

    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;
    public String username;
    public long timestamp;
    public boolean isRegistered;
    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> {

    public String convertToDb(Uri model) {
        return model == null ? null : model.toString();

    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