Sql2o on Android - aaberg/sql2o GitHub Wiki

Copy/pasted from a comment by migel on issue #140.

I've tested Sq2o with both H2 and Sqlite. Using H2 is quite simple, just put the sql2o-1.5.2.jar and h2-1.4.181.jar into the libs folder of the Android project. Then in onCreate (not shown below but you could also use flyway http://flywaydb.org/documentation/api/ to manage schema upgrades):

File dbDir = context.getDir("db", 0);
dbUrl = "jdbc:h2:file:" + dbDir.getPath() + "/mydb" +
        ";FILE_LOCK=FS;PAGE_SIZE=1024;CACHE_SIZE=8192";
dbUser = "sa";
sql2o = new Sql2o(dbUrl, dbUser, "");

The options for H2 are as recommended in http://h2database.com/html/tutorial.html#android .

Android doesn't support try with resources prior to API level 19 so you have to use the following pattern instead:

Connection con = sql2o.open();
try {

}
finally {
    con.close();
}

I've tested simple queries; the ones I've found to work include inserts and updates with addParameter() and bind(). Select queries also work for POJOs using fields and using accessors functions; addColumnMapping also works.

Using sqlite is more complicated. Android doesn't include a JDBC driver for the built in sqlite. There is a project https://github.com/SQLDroid/SQLDroid that implements a JDBC driver above the android.database.* classes. To use it put the sqldroid-1.0.3.jar in the libs folder.

So far I've run into issues with this driver that are related to generated keys: it doesn't implement the Connection.prepareStatement(String sql, int autoGeneratedKeys) and PreparedStatement.getGeneratedKeys() methods yet.

The main branch of SqlDroid seems to have a fix for the first missing method but for now you can work around it by creating a quirks class:

import java.util.Map;

import org.sql2o.converters.Converter;
import org.sql2o.quirks.NoQuirks;

public class SqlDroidQuirks extends NoQuirks {
    public SqlDroidQuirks() {
        super();
    }
    
    public SqlDroidQuirks(Map<Class, Converter> converters) {
        super(converters);
    }
    
    @Override
    public boolean returnGeneratedKeysByDefault() {
        return false;
    }
}

And to use it:

SQLiteDatabase sqliteDB;
sqliteDB = context.openOrCreateDatabase("mydb", 0, null);
dbUrl = "jdbc:sqlite:" + sqliteDB.getPath();
dbUser = "";
sqliteDB.close();

sql2o = new Sql2o(dbUrl, dbUser, "", new SqlDroidQuirks());

These missing methods also mean you can't use Sql2o Connection.getKey() to retrieve the generated key. I've opened an issue about it https://github.com/SQLDroid/SQLDroid/issues/50. For now you can use a workaround:

Connection con = sql2o.beginTransaction();
try {
    con.createQuery("INSERT ...")
       .executeUpdate();
    int key = con.createQuery("SELECT last_insert_rowid();")
                 .executeScalar(Integer.class);
    con.commit();
    return key;
}
finally {
    con.close();
}

Finally, the Android log complains about missing some sun.reflect.* classes and the java.beans.Introspector.decapitalize method but so far it doesn't seem to affect anything.