Android SQLite学习

来源:互联网 发布:数据库管理员简历 编辑:程序博客网 时间:2024/06/10 05:08

1、定义模式和合约类

SQLite数据库中一个比较主要的概念就是Schema(模式):对数据库如何进行组织的一种形式化定义。模式就反映在我们用来创建数据库的SQL语句上。

同样地,创建一个辅助类,也就是合约类,它以一种系统的、自我描述的方式显式地指定了这个模式的布局。合约类包含了URI,表,列的名字的常量。我们需要在合约类的顶层里存放我们数据库的全局定义,然后在这个类里面创建一个个内部类,来描述每个表的内容。
注意:通过实现BaseColumns接口,我们的内部类就能继承一个称之为_ID的主键
下面举例说明:
public static abstract class FeedEntry implements BaseColumns {    public static final String TABLE_NAME = "entry";    public static final String COLUMN_NAME_ENTRY_ID = "entryid";    public static final String COLUMN_NAME_TITLE = "title";    public static final String COLUMN_NAME_SUBTITLE = "subtitle";    ...}
为了避免实例化这个合约类,我们需要这样定义构造函数:
private FeedReaderContract() {}


2、使用SQL Helper创建数据库

当定义好数据库之后,我们应该实现创建和管理数据库和表的方法。下面是创建和删除表的典型语句:
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);