在 SQL 数据库中保存数据
2016-05-26 09:55
375 查看
在 SQL 数据库中保存数据
上一课下一课
本课程将向您展示如何
定义架构和契约使用 SQL 辅助工具创建数据库
将信息输入到数据库
从数据库读取信息
从数据库删除信息
更新数据库
您还应阅读
使用数据库将数据保存到数据库对于重复或结构化数据(比如契约信息) 而言是理想之选。本课程假定您基本熟悉 SQL 数据库并且可帮助您开始在 Android 中使用 SQLite 数据库。 您在 Android 中使用数据库所需的 API 在
android.database.sqlite软件包中提供。
定义架构和契约
SQL 数据库的主要原则之一是架构:数据库如何组织的正式声明。 架构体现于您用于创建数据库的 SQL 语句。您会发现它有助于创建伴随类,即契约 类,其以一种系统性、自记录的方式明确指定您的架构布局。契约类是用于定义 URI、表格和列名称的常数的容器。 契约类允许您跨同一软件包中的所有其他类使用相同的常数。 您可以在一个位置更改列名称并使其在您整个代码中传播。
组织契约类的一种良好方法是将对于您的整个数据库而言是全局性的定义放入类的根级别。 然后为枚举其列的每个表格创建内部类。
注意:通过实现
BaseColumns接口,您的内部类可继承调用的主键字段
_ID,某些
Android 类(比如光标适配器)将需要内部类拥有该字段。 这并非必需项,但可帮助您的数据库与 Android 框架协调工作。
例如,该代码段定义了单个表格的表格名称和列名称:
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;
就像您在设备的内部存储中保存文件那样,Android 将您的数据库保存在私人磁盘空间,即关联的应用。
您的数据是安全的,因为在默认情况下,其他应用无法访问此区域。
SQLiteOpenHelper类中有一组有用的
API。当您使用此类获取对您数据库的引用时,系统将只在需要之时而不是 应用启动过程中执行可能长期运行的操作:创建和更新数据库。 您只需调用
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());
将信息输入到数据库
通过将一个ContentValues对象传递至
insert()方法将数据插入数据库:
// 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);
insert()的第一个参数即为表格名称。第二个参数指定在
ContentValues为空的情况下框架可在其中插入
NULL 的列的名称(如果您将其设置为
"null", 那么框架将不会在没有值时插入行。)
从数据库读取信息
要从数据库中读取信息,请使用, java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String)]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()开始,其将“读取位置”置于结果中的第一个条目中。 对于每一行,您可以通过调用
Cursor获取方法之一读取列的值,比如
getString()或
getLong()。对于每种获取方法,您必须传递所需列的索引位置,您可以通过调用
getColumnIndex()或
getColumnIndexOrThrow()获取。例如:
cursor.moveToFirst(); long itemId = cursor.getLong( cursor.getColumnIndexOrThrow(FeedEntry._ID) );
从数据库删除信息
要从表格中删除行,您需要提供识别行的选择条件。 数据库 API 提供了一种机制,用于创建防止 SQL 注入的选择条件。 该机制将选择规范划分为选择子句和选择参数。 该子句定义要查看的列,还允许您合并列测试。 参数是根据捆绑到子句的项进行测试的值。由于结果并未按照与常规 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()的
where句法相结合。
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);
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories