对于重复的或结构化的数据,保存到数据库中是很好的选择,比如联系人信息。这里假设你对SQL数据库大体上了解然后帮助你学习Android上的SQLite数据库。在Android数据库上需要用到的API可以在android.database.sqlite包中找到。

定义Schema和Contract

SQL数据库中一个主要的准测是schema:一个正式的数据库如何组织的声明。这个schema和用来创建数据库的SQL声明是对应的。你会发现创建一个同样的类很有用,叫做contract类,它明确指名了schema在系统中的设计和自己记录的方式。

contract类是一个常量(URI的名字,表,列)的容器,contract类可以让你在同一个包的其他类中使用同样的常量.这样可以让你只在一个地方改变列名就可以在所有代码中使用。

一个好的组织contract类的方法是把对于整个数据库全局的定义放到类的根层次。然后为每张表创建内部类来列举它们的列。

注意:通过实现BaseColumns接口,内部类可以继承一个主键_ID,很多Android类都期望有这个。虽然不是必须的,但是这样可以帮你的数据库和Android framwork和谐的工作。

例如,这段代码为一个表定义了表明和列名:

 public final class FeedReaderContract {
// 为了防止谁意外的实例化contract类
// 给它一个空的构造器
public FeedReaderContract() {} /* 定义表内容的内部类 */
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。当使用这个类来获得数据库引用时,系统在需要的时候会潜在的长时间运行创建和更新数据库操作,并不是在app启动时。你只需要调用getWritableDatabase()或者getReadableDatabase().

注意:因为它们可以长时间运行,确保在后台线程中调用getWritableDatabase()或者getReadableDatabase(),比如用AsyncTash或者IntentService

为了使用SQLiteOpenHelper,创建一个子内然后重写onCreate(),onUpgrade()和onOpen()回调方法。也可以实现onDowngrade(),但是不是必须的。

例如,这里有一个使用上面方法的SQLiteOpenHelper的实现:

 public class FeedReaderDbHelper extends SQLiteOpenHelper {
// 如果改变了数据库的schema,必须要增加数据库的版本。
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());

往数据库存数据

通过传递ContentValues对象给insert()方法可以往数据库插入数据:

 // 获得写模式的数据仓库
SQLiteDatabase db = mDbHelper.getWritableDatabase(); //创建一个带值的表,它们的列名是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); //插入新的行,返回新行的主键值
long newRowId;
newRowId = db.insert(
FeedEntry.TABLE_NAME,
FeedEntry.COLUMN_NAME_NULLABLE,
values);

inert()的第一个参数是表名,第二个参数提供了一些在ContentValues为空时可以插入NULL的列名(如果把这个设置为null,当没有值时,framework不会插入一行)。

从数据库读信息

为了读数据库,调用query()方法,传递你的选择标准和需要的列。这个方法联合了insert()和update(),期望得到的列是要获得的数据,而不是要插入的数据。结果会在一个Cursor对象中返回。

 SQLiteDatabase db = mDbHelper.getReadableDatabase();

 // 定义一个projection来指定数据库中的那些列在查询后会使用
String[] projection = {
FeedEntry._ID,
FeedEntry.COLUMN_NAME_TITLE,
FeedEntry.COLUMN_NAME_UPDATED,
...
}; // 在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中的行,使用Cursor的move方法,在读值之前必须要调用。总体上,应该首先调用moveToFirst(),它可以把读的位置指向结果的第一个条。对于每一行,可以调用Cursor的get方法,比如getString()或getLong()来读列的值。对于每个get方法,需要传递期望的列的索引位置,可以通过调用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();

 // 列的新值
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title); // 根据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);
 

Android - 数据存储 -在SQL数据库中保存数据的更多相关文章

  1. 【Android Developers Training】 26. 在SQL数据库中保存数据

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. 利用POI工具读取word文档并将数据存储到sqlserver数据库中

    今天实现了利用POI工具读取word文档,并将数据存储到sql数据库中,代码如下: package word; import java.io.File; import java.io.FileInpu ...

  3. 如何将存储在MongoDB数据库中的数据导出到Excel中?

    将MongoDB数据库中的数据导出到Excel中,只需以下几个步骤: (1)首先,打开MongoDB安装目录下的bin文件夹,(C:\Program Files (x86)\MongoDB\Serve ...

  4. C#-WinForm-ListView-表格式展示数据、如何将数据库中的数据展示到ListView中、如何对选中的项进行修改

    在展示数据库中不知道数量的数据时怎么展示最好呢?--表格 ListView - 表格形式展示数据 ListView 常用属性 HeaderStyle - "详细信息"视图中列标头的 ...

  5. c#.net Excel中的数据导入到SQL数据库中

    /// <summary>        /// 从Excel 导入学生        /// </summary>        /// <param name=&qu ...

  6. 通过ArcGIS将数据存储到SQL Server2012中

    一.软件安装: ARCGIS 10.3安装 SQLserver2012安装 ARCGIS 10.3 安装(注意ARCGIS10.3并不用安装配置ARCSDE). https://wenku.baidu ...

  7. 【Android Developers Training】 23. 序言:保存数据

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. SQL语句:把Excel文件中数据导入SQL数据库中的方法

    1.从Excel文件中,导入数据到SQL数据库情况一.如果接受数据导入的表不存在 select * into jd$ from OPENROWSET('MICROSOFT.JET.OLEDB.4.0' ...

  9. Session如何保存在sql数据库中

    aspnet中,session默认以inproc模式存储,也就是保存在iis进程中,这样有个优点就是效率高,但不利于为本负载均衡扩展.可以把session信息保存在SQL Server中,据说,该种方 ...

随机推荐

  1. 你真的了解mysql的varchar字段的长度有多少吗?

    今天在设计系统字段的时候, 发现自己对varchar还不够了解.我设了一个字段.类型为VARCHER,然后我就往里面测试性了写了东西.发现没有多少就满了.我觉得奇怪,5.5版本以上的MYSQL不是有6 ...

  2. Visual Studio使用正则表达式快速统计总共代码行数

    原文:Visual Studio使用正则表达式快速统计总共代码行数 按CTRL+SHIFT+F,勾上支持正则表达式,然后输入搜索内容: <span style="font-family ...

  3. 低版本的 opencv库的 vs2010 打开 高版本opencv

    打开track.vcxproj文件, 注释掉跟版本有关的行就可. 本例子中,当用双击.sln用vs2010打开高版本的opencv项目时,会出现错误, 并且会有错误信息提示,双击该错误信息,就会打开该 ...

  4. 碎碎念,浅饮-------Day30

    这不是关于技术的文章,它偏离了我原来的计划轨迹.但,我相信这将是远远超出了技术的意义使我无论什么价格值. 高考已经开始,不知道在这片宁静的夜空下有多少人已经美美的睡了,香甜憨然.又有多少人这睡着的眼角 ...

  5. 让CentOS系统时间同步

    CentOS系统时间同步的步骤如下: 新装的CentOS系统服务器可能设置了错误的,需要调整时区并调整时间. 如下是CentOS系统使用NTP来从一个时间服务器同步cp /usr/share/zone ...

  6. uvaLive5713 次小生成树

    uvaLive5713 修建道路使得n个点任意两点之间都可以连通,每个点有都有一定的人口,现在可以免费修一条道路, A是免费修的道路两端结点的人口之和, B的其它不是免费修道路的长度的总和 要求的是A ...

  7. 主席树(可持久化线段树) 静态第k大

    可持久化数据结构介绍 可持久化数据结构是保存数据结构修改的每一个历史版本,新版本与旧版本相比,修改了某个区域,但是大多数的区域是没有改变的, 所以可以将新版本相对于旧版本未修改的区域指向旧版本的该区域 ...

  8. Android Material Design-Creating Lists and Cards(创建列表和卡)-(三)

    转载请注明出处:http://blog.csdn.net/bbld_/article/details/40430319 翻译自:http://developer.android.com/trainin ...

  9. 将Excel数据表到数据库表

    假设你有大量的数据要导入到数据库表,恐怕是没有效率的写程序,作为用于数据操纵,Excel在这方面有优势,但是,如何将其结合起来?将Excel数据表到数据库表,就是本篇博客的目的. 首先去下载MySQL ...

  10. 1104. Don’t Ask Woman about Her Age(数论)

    a*b^n(mod(b-1) =a(mod(b-1) http://acm.timus.ru/problem.aspx?space=1&num=1104 #include <stdio. ...