当定义好数据库之后,我们应该实现创建和管理数据库和表的方法。下面是创建和删除表的典型语句:
private static final String TEXT_TYPE = " TEXT";private static final String COMMA_SEP = ",";private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + FeedReaderContract.FeedEntry.TABLE_NAME + " (" + FeedReaderContract.FeedEntry._ID + " INTEGER PRIMARY KEY," + FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + ... // Any other options for the CREATE command " )";private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + TABLE_NAME_ENTRIES;
就像保存在内部存储器里的文件一样,Android将我们创建的数据库保存在它对应的应用程序私有空间里,这样就保证了我们的数据是安全的,不会为其他应用程序利用。
当我们通过SQLiteOpenHelper这个类取得数据库的引用时,系统在需要而且不是应用启动期间,可能会执行长时间的创建和更新数据库的操作。所有对数据库的操作都是通过调用getWritableDatabase()或getReadableDatabase()来做的。
(注意:由于上述操作有可能是耗时的,所以确保是在后台线程里调用getWritableDatabase()或getReadableDatabase()。)
为了使用SQLiteOpenHelper,我们需要创建一个它的子类,并实现onCreate(),onUpgrade()和onOpen()等回调方法,有需要的话还可以实现onDowngrade()方法。下面举例说明:public class FeedReaderDbHelper extends SQLiteOpenHelper { // 如果改变了数据库的模式,就需要增加数据库的版本号. 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) { // 这个数据库仅仅是在线数据的缓存,因此它的更新策略就是简单地丢弃旧数据并重新开始 db.execSQL(SQL_DELETE_ENTRIES); onCreate(db); } public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { onUpgrade(db, oldVersion, newVersion); }}
然后,就可以通过下面的语句来实例化我们自己的SQLiteOpenHelper了:FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
3、往数据库添加数据
我们是通过给insert()方法传递一个ContentValues对象来往数据库中插入数据的:// 以写方式取得数据库SQLiteDatabase db = mDbHelper.getWritableDatabase();// 创建一组values的map,其中列名作为keyContentValues values = new ContentValues();values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID, id);values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_CONTENT, content);// 插入新的一行,然后返回这行的主键long newRowId;newRowId = db.insert( FeedReaderContract.FeedEntry.TABLE_NAME, FeedReaderContract.FeedEntry.COLUMN_NAME_NULLABLE, values);
insert()方法的第一个参数是表名,第二个参数则提供了当ContentValues为空时也能插入新行的那些允许插入NULL值的列(如果这个参数设为null,当没有给那些允许为空的列提供值的时候,则不会插入新行)。
4、从数据库读取信息
我们可以通过给query()方法传递选择条件和查询列来从数据库读取数据。这个方法结合了insert()和update()方法中的参数,只是这个选择列的列表定义的是我们想要获取的数据,而不是要插入的数据。查询结果返回一个Cursor对象。SQLiteDatabase db = mDbHelper.getReadableDatabase();// 指定了要查询的列String[] projection = { FeedReaderContract.FeedEntry._ID, FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED, ... };// 查询结果的排序方式String sortOrder = FeedReaderContract.FeedEntry.COLUMN_NAME_UPDATED + " DESC";Cursor c = db.query( FeedReaderContract.FeedEntry.TABLE_NAME, // 查询的表 projection, // 要返回的列 selection, // 查询条件 selectionArgs, // 查询条件的参数 null, // 列的分组 null, // 过滤列的分组 sortOrder // 排序方式 );
为了查看查询结果中的行,我们必须在读取数据之前使用Cursor的移动方法。通常来说,我们使用moveToFirst()方法来把初始读取位置定位到第一行。对于Cursor中的每一行数据,我们可以使用Cursor的获取方法来读取列的值,比如getString()或getLong()这样的方法,对于这样的每一个读取方法,要指定你想获取的列索引。比如:cursor.moveToFirst();long itemId = cursor.getLong( cursor.getColumnIndexOrThrow(FeedReaderContract.FeedEntry._ID));
5、从数据库中删除数据
为了从表中删除数据,我们需要提供选择条件。数据库的API提供了一种能够防止SQL注入的创建查询条件的机制,这种机制即是将选择语句和选择参数分离。比如:// 定义查询条件String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";// 指定查询参数String[] selectionArgs = { String.valueOf(rowId) };// 处理查询db.delete(table_name, selection, selectionArgs);
6、更新数据库
使用update()方法来更新数据库中的数据,实际上是insert()和delete()的结合。例如:SQLiteDatabase db = mDbHelper.getReadableDatabase();// 定义列的新值ContentValues values = new ContentValues();values.put(FeedReaderContract.FeedEntry.COLUMN_NAME_TITLE, title);// 基于ID来确定哪行被更新String selection = FeedReaderContract.FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";String[] selectionArgs = { String.valueOf(rowId) };int count = db.update( FeedReaderDbHelper.FeedEntry.TABLE_NAME, values, selection, selectionArgs);