Data Storage Overview Sqlite Databases
Data Storage Overview Sqlite Databases
com/
// Query the given table, returning a Cursor over the result set.
// The Cursor object is a reference to the data
Cursor cur = db.query(table, columns, selection, selectionArgs,
groupBy, having, orderBy);
cur = db.query(distinct, table, columns, selection, selectionArgs,
groupBy, having, orderBy, limit);
SQL Querys → function
• query(String table, String[] columns, String
selection, String[] selectionArgs, String groupBy,
String having, String orderBy)
• SELECT _id, word, definition FROM table_words
• Translates into
db.query("table_word",
new String[] {"_id",
"word", "definition"},
null, null, null, null, null
);
Example DB, execSQL()
• DatabaseTest example app -
A database with book titles
– A modified DatabaseActivity
and DBAdapter class which in turn contains a static DatabaseHelper class
which extends the SQLiteOpenHelper class
– http://www.devx.com/wireless/Article/40842/1954
• execSQL() can execute a single SQL statement that is NOT a SELECT
or any other SQL statement that does not return any data
• For complex queries returning a cursor - use SQLiteQueryBuilder.query()
// Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
db.execSQL("DROP TABLE IF EXISTS books");
// This is a convience class that helps build SQL queries to be sent to SQLiteDatabase objects.
SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
qBuilder.setTables("example et JOIN secondtable st ON et.id = st.example_id");
qBuilder.appendWhere(" et.someRow = ? ");
Cursor cursor = qBuilder.query(sqlitedatabase, projection, selection, selectionArgs, null, null, sortOrder);
startManagingCursor(cursor);
Create a table and delete a row
• The Activity.startManagingCursor(cursor) on previous slide allows the activity to
take care of managing the given Cursor's lifecycle based on the activity's lifecycle - it
requires that the row key id is named "_id".
• startManagingCursor(cursor) is deprecated since API 11. Use the new CursorLoader
class with LoaderManager instead! It will manage the cursor in a similar way.
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
try {
// insert/delete/update records
// Marks the current transaction as successful.
db.setTransactionSuccessful();
}
catch(SQLiteException ex) {
Log.d("Transaction exception", ex.getMessage());
}
finally {
// End a transaction.
db.endTransaction();
}
SQLiteOpenHelper
• Create a subclass implementing onCreate(SQLiteDatabase),
onUpgrade(SQLiteDatabase, int, int) and optionally
onOpen(SQLiteDatabase), and this class takes care of opening the
database if it exists, creating it if it does not, and upgrading it as necessary.
• Transactions are used to make sure the database is always in a sensible
state.
• This class makes it easy for ContentProvider implementations to delay
opening and upgrading the database until first use, to avoid blocking
application startup with long-running database upgrades.
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(DATABASE_CREATE);
}
catch(SQLiteException ex) {
Log.d("Create table exception", ex.getMessage());
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(Consts.TAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + Consts.DATABASE_TABLE);
onCreate(db);
}
}
(Android) Databases,
design considerations
• Use (extend from) SQLiteOpenHelper to manage database creation
and version management
• Write an “adapter class”, with (strongly typed) methods, hiding the
database manipulation, and constants representing keys
– Example DbAdapter.java in the books Database test example app
• Model rows as class instances
• SQLite does not enforce foreign key constraints – use triggers
instead (via execSQL), trigger == attached stored pocedure
– http://www.sqlteam.com/article/an-introduction-to-triggers-part-i
• Don’t store large files (media etc.) in the database
• Data type integrity and referential integrity is not maintained in SQLite
• Full Unicode support (UTF-16) is optional, UTF-8 is used by default
• http://www.codeproject.com/Articles/119293/Using-SQLite-
Database-with-Android
Example database 1
• It's good practice to create a DB adapter class to encapsulate all the
complexities of accessing the database so it's transparent to the calling code
// From: http://www.devx.com/wireless/Article/40842
private static final String DATABASE_CREATE = "create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, publisher text not null);";
private final Context mContext;
private DatabaseHelper mDBHelper;
private SQLiteDatabase mDB;
// SQLiteDatabase has methods to create, delete, execute SQL commands and perform other common database management tasks
public DBAdapter(Context ctx)
{
this.mContext = ctx;
mDBHelper = new DatabaseHelper(mContext, DATABASE_NAME, null, DATABASE_VERSION);
}
// Within the DBAdapter class, we extend the DataBaseHelper with the SQLiteOpenHelper class —
// an Android helper class for database creation and versioning management.
// In particular, we override the onCreate() and onUpgrade() methods.
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE); //in this string we have our SQL create table statement
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
Example database 2
• Some usage examples from DatabaseActivity and DBAdepter
public class DatabaseActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDBA = new DBAdapter(this);
}
...
mDBA.open();
mDBA.insertTitle("0470285818", "C# 2008 Programmer's Reference", "Wrox");
----------------------------------------------------------------------------------------
public class DBAdapter {
private DatabaseHelper mDBHelper;
// SQLiteDatabase has methods to create, delete, execute SQL commands and perform other common database management tasks
private SQLiteDatabase mDB;
--------------------------------------------------------------------------------------------
public class DBAdapter {
//---retrieves a cursor for a particular title---
//public Cursor query (boolean distinct, String table, String[] columns, String selection,
//String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
public Cursor getTitle(long rowId)
{
return mDB.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID, KEY_ISBN, KEY_TITLE, KEY_PUBLISHER },
KEY_ROWID + "=" + rowId, null, null, null, null, null);
}
}
//---deletes a particular title---
public boolean deleteTitle(long rowId) {
return = mDB.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}