(一)开始____6、保存数据——在SQL数据库中保存数据

目录

 [隐藏

在SQL数据库中保存数据

将数据保存在数据库中是重复或结构化数据(例如联系人信息)的理想方式。假设你熟悉SQL数据库,该类可以帮助你开始使用安卓的SQLite数据库。要使用安卓数据包的API在android.database.sqlite包可用。

定义模式和合约

SQL数据库主要原则之一就是模式:数据库组成方式的正式声明。模式在创建数据库的SQL语句中得以反映。这有助于创建相应配套类即 contract class ,它以系统和自记录方式明确规定了主题布局。
contract class 是一个定义URI、表和列名称的常量集。 contract class 允许你在同一包内使用相同的常量,由此就能够更改列名称并且在代码中传播。
对整个数据库在根节点进行全局定义是组建 contract class的好办法。然后为每个枚举列的资料表创建内部类。
例如以下代码段定义了单个表格的表名称和列名称:
public final class FeedReaderContract {
    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    public FeedReaderContract() {}
 
    /* Inner class that defines the table contents */
    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";
        ...
    }
}

使用SQL辅助创建数据库

一旦定义了数据库状态,就应该实现创建和维护数据库及表的做法。下面是创建和删除表中的典型语句:
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
    FeedEntry._ID + " INTEGER PRIMARY KEY," +
    FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
    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 " + FeedEntry.TABLE_NAME;
就像保存在设备内部存储的文件一样,安卓在关联应用程序的私人磁盘空间来存储你的数据库。数据很安全,因为默认情况下这个区域无法访问其他应用程序。
API集在 SQLiteOpenHelper 类中是可用的。当你使用该类来获取数据库时,仅当需要时系统才会执行创建和更新数据库潜在长期运行的操作。你要做的事情就是调用getWritableDatabase()或getReadableDatabase()。
注意:因为他们可以长时间运行,请确保你在后台调用 了getWritableDatabase() 或getReadableDatabase(),例如 AsyncTask 或IntentService。
为了使用 SQLiteOpenHelper,创建一个覆盖 onCreate(), onUpgrade() 和onOpen()回调方法的子类。你还可以实施 onDowngrade(),虽然这不是必需的。
例如使用上述显示命令行实现SQLiteOpenHelper:
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);
    }
}
为了访问数据库,需要实例化 SQLiteOpenHelper的子类:
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

将信息放入数据库

向 insert()方式传递 ContentValues 对象就可以将数据插入到数据库。
// 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_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
 
// Insert the new row, returning the primary key value of the new row
long newRowId;
newRowId = db.insert(FeedEntry.TABLE_NAME, FeedEntry.COLUMN_NAME_NULLABLE, values);

从数据库读取信息

使用 query() 方法从数据库中读取,把你的选择标准和所需列传递给它。这个方法把 insert() 和update()元素结合在一起,注意列的列表定义要获取的数据而不是要插入的数据。查询结果作为 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_UPDATED,
    ...
    };
 
// How you want the results sorted in the resulting Cursor
String sortOrder = FeedEntry.COLUMN_NAME_UPDATED + " DESC";
 
Cursor c = 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移动方法,在开始读值之前你必须始终调用该方法。通常开始会调用 moveToFirst(),对于每一行都可以调用光标方式来进行列表读值,比如 getString() 或者getLong().
对于每一个get方法,必须调用 getColumnIndex() 和getColumnIndexOrThrow()得到所需列的索引位置,进而传递出去。例如:
cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);

从数据库中删除信息

要删除表中的行,需要提供确定行的选择标准。数据库API提供了一种用于创建选择标准的机制。该机制把选择规范划分为选择条款和选择参数。这一参数是用来测试绑定条款的值。因为结果与普通SQL语句处理不完全相同,SQL插入不会对它产生影响。
// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(rowId) };
// Issue SQL statement.
db.delete(table_name, selection, selectionArgs);

更新数据库

当你需要修改数据库值的子集时,使用 update()方式。
结合 insert()和 delete()内容值语法来更新资料表。
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 ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
 
int count = db.update(
    FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values,
    selection,
    selectionArgs);
 
posted @ 2014-07-29 16:06  ╰→劉じ尛鶴  阅读(405)  评论(0)    收藏  举报