Android数据存储之使用数据库存储

时间:2022-09-18 22:59:42

对于结构化的数据用数据库存储是再好不过的,Android官方支持SQLite数据库。所以Android中的数据库操作就是对SQLite数据库进行操作,为此Android中的android.database.sqlite包提供了一系列的API进行数据库操作,可以看成是一个针对SQLite数据库的抽象层。

定义Schema和Contract

Schama就是一个正式的关于数据库是如何组织的描述。对应起来就是创建数据库的SQL语句。同时还有一个Schema的合作类Contract,可以提供创建数据库的一些信息。

public final class FeedReaderContract {
private FeedReaderContract() {}

public static class FeedEntry implements BaseColumns {

public static final String TABLE_NAME = "entry";
public static final String COLUMN_NAME_TITLE = "title";
public static final String COLUMN_NAME_SUBTITLE = "subtitle";
}
}

如上代码,Contract类里包含了一些创建数据库时需要使用的名字,表名、字段名等。这样的好处是在一个地方改变一个字段名就可以在所有使用的代码中生效。

上面代码实现了一个BaseColumn接口,会给实现它的类一个_ID作为记录的一个primary key。这个字段在Android framework中很多其它类都会使用,所以虽然并不是强制实现这个接口单实现了会方便很多。

使用SQLHelper创建数据库

在创建了数据库后,就可以实现一些方法来创建和删除数据表。Android中数据库文件会以private模式存储到内存存储中。其它的APP不能访问数据。

private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
FeedEntry._ID + " INTEGER PRIMARY KEY," +
FeedEntry.COLUMN_NAME_TITLE + " TEXT," +
FeedEntry.COLUMN_NAME_SUBTITLE + " TEXT)";

private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;

通过SQLHelper类的getWritableDatabase()或者getReadableDatabase()这两个方法可以得到数据库的引用(references),然后就可以操作数据库了。同时这两个方法是耗时操作,所以不要放在UI线程。

使用SQLiteOpenHelper类的方式是通过继承它来重写其中的onCreate(),onUpgrade(),onOpen()方法,在其中实现自己的业务需求。实例代码如下:

public class FeedReaderDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";

public FeedReaderDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}


向数据库中存入数据

要向数据库中存入数据,要准备好存入的数据。在Android用ContentValues来表示存入的数据,它是一个map,键名就是表的字段名,值就是对应字段的值。
代码示例:

// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);

// Insert the new row, returning the primary key value of the new row
long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);


从数据库中查询数据

从一个数据库中读出数据是通过query()这个方法,值得注意的是它的参数列表。最后这个query()方法返回的是一个Cursor对象,对Cursor对象进行迭代从而得到要查询的数据。

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
FeedEntry._ID,
FeedEntry.COLUMN_NAME_TITLE,
FeedEntry.COLUMN_NAME_SUBTITLE
};

// Filter results WHERE "title" = 'My Title'
String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = { "My Title" };

// How you want the results sorted in the resulting Cursor
String sortOrder =
FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";

Cursor cursor = db.query(
FeedEntry.TABLE_NAME, // The table to query
projection, // The columns to return
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);

从Cursor对象中获取数据

List itemIds = new ArrayList<>();
while(cursor.moveToNext()) {
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(FeedEntry._ID));
itemIds.add(itemId);
}
cursor.close();


删除数据库中的数据

// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { "MyTitle" };
// Issue SQL statement.
db.delete(FeedEntry.TABLE_NAME, selection, selectionArgs);


更新数据库中的数据

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);

// Which row to update, based on the title
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = { "MyTitle" };

int count = db.update(
FeedReaderDbHelper.FeedEntry.TABLE_NAME,
values,
selection,
selectionArgs);


维持一个数据库连接

调用getWritableDatabase()getReadableDatabase()方法来建立一个数据库连接是一个耗费性能的操作,所以最好是在不需要数据库功能后才将连接关闭。典型场景就是在activity的onDestroy()方法中关闭数据库连接。

@Override
protected void onDestroy() {
mDbHelper.close();
super.onDestroy();
}

总结一下,Android中采用的数据库是SQLite数据库。为了简化SQLite数据库的操作,提供了sqlite包。得到SQLite数据库实例的最好方式就是继承SQLiteHelper创建其子类。在得到数据库实例后就可以通过不同的API方法进行数据库数据的增删改查等操作。