(一)开始____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);

浙公网安备 33010602011771号