patternjavaMinor
Android SQLite Database management
Viewed 0 times
databasemanagementsqliteandroid
Problem
I'd like some opinions about my approach at using SQLite databases in android. Everything seems to work very well, but there may be something wrong that I hadn't noticed.
I don't like working with create/alter table statements in code, so I prefer creating my database with some SQLite client out there and putting it in assets folder. I use some logic to decide when the database must be replaced and which records need to be kept, then use this code in a class called DbManager:
```
private static SQLiteDatabase _db = null;
public static Object lock = new Object();
private static SQLiteDatabase getDB() {
if (_db == null) {
_db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
}
return _db;
}
//this is the approach used for insert operations, but is the same for update, delete etc
public static boolean insert(String tableName, ContentValues values) {
try {
return getDB().insert(tableName, null, values) >= 0;
} catch (Exception e) {
LogHelper.WriteLogError("error in DB_manager.insert function", e);
return false;
}
}
public static synchronized void beginTransaction(String who) {
LogHelper.WriteLogDebug("starting transaction by " + (who == null ? "null" : who));
try {
//in this way if a transaction is still executing it waits untill the previus ends.
//obviously every time i call DbManager.beginTransaction the call at DbManager.endTransaction is in the finally statment
if (_db.inTransaction()) {
LogHelper.WriteLogInfo("DB IS IN TRANSACTION");
synchronized (lock) {
lock.wait();
}
}
getDB().beginTransactionWithListener(new SQLiteTransactionListener() {
@Override
public void onRollback() {
synchronized (lock) {
LogHelper.WriteLogInfo("onRollback listener invoked");
I don't like working with create/alter table statements in code, so I prefer creating my database with some SQLite client out there and putting it in assets folder. I use some logic to decide when the database must be replaced and which records need to be kept, then use this code in a class called DbManager:
```
private static SQLiteDatabase _db = null;
public static Object lock = new Object();
private static SQLiteDatabase getDB() {
if (_db == null) {
_db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
}
return _db;
}
//this is the approach used for insert operations, but is the same for update, delete etc
public static boolean insert(String tableName, ContentValues values) {
try {
return getDB().insert(tableName, null, values) >= 0;
} catch (Exception e) {
LogHelper.WriteLogError("error in DB_manager.insert function", e);
return false;
}
}
public static synchronized void beginTransaction(String who) {
LogHelper.WriteLogDebug("starting transaction by " + (who == null ? "null" : who));
try {
//in this way if a transaction is still executing it waits untill the previus ends.
//obviously every time i call DbManager.beginTransaction the call at DbManager.endTransaction is in the finally statment
if (_db.inTransaction()) {
LogHelper.WriteLogInfo("DB IS IN TRANSACTION");
synchronized (lock) {
lock.wait();
}
}
getDB().beginTransactionWithListener(new SQLiteTransactionListener() {
@Override
public void onRollback() {
synchronized (lock) {
LogHelper.WriteLogInfo("onRollback listener invoked");
Solution
The code looks fine to me but it is a bit odd because the official docs recommend creating a
SQLiteOpenHelper subclass to handle database interaction. And if you use one SQLiteOpenHelper instance across your application, it will be thread-safe so there's no need to add your own synchronization logic:public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "location_scout.db";
private static final int SCHEMA_VERSION = 1;
// Singleton pattern
private static DatabaseHelper instance;
public synchronized static DatabaseHelper getInstance(Context context) {
if(instance == null) {
instance = new DatabaseHelper(context.getApplicationContext());
}
return instance;
}
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
}Code Snippets
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "location_scout.db";
private static final int SCHEMA_VERSION = 1;
// Singleton pattern
private static DatabaseHelper instance;
public synchronized static DatabaseHelper getInstance(Context context) {
if(instance == null) {
instance = new DatabaseHelper(context.getApplicationContext());
}
return instance;
}
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
}Context
StackExchange Code Review Q#28605, answer score: 6
Revisions (0)
No revisions yet.