Android SQLite学习

本文详细介绍了如何在Android应用中使用SQLite数据库,包括定义模式和合约类、创建数据库、添加、读取、删除和更新数据等关键步骤。
摘要由CSDN通过智能技术生成

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,其中列名作为key
ContentValues 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);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值