前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[翻译]Android教程-保存数据-在SQL数据库中保存数据

[翻译]Android教程-保存数据-在SQL数据库中保存数据

作者头像
LeoXu
发布2018-08-15 14:41:35
1.8K0
发布2018-08-15 14:41:35
举报
文章被收录于专栏:LeoXu的博客LeoXu的博客

定义一个 Schema 和 Contract


SQL数据库的主要原则是模式(schema): 一种数据库被如何组织的正式声明. 模式被反映在你用来创建你的数据库的SQL语句中. 你可能会发现创建一个同伴类很有用,它被称作(contract)协议类, 它用一种系统和自文档化的方式明确指定了你的模式的布局.

协议类是定义的URI、表格和列名称常量的容器. 协议类让你可以在同一个包的所有其它类那里使用相同的常量. 这让你可以在一个地方对列名称的改变传播到你所有的代码.

组织一个协议类最好的方式是将对你的整个数据库全局可用的定义放置到类的根一级别 . 然后为每一个表创建一个内部类,并枚举出它们的列.

注意: 通过实现 BaseColumns 接口, 你的内部类可以继承到一个称作 _ID 的主键域,一些诸如游标适配器的Android类将希望有这个东西 . 它也不是一定要有的,但它有助于你的数据库同Android框架更加的协调 .

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

代码语言:javascript
复制
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 Helper 创建一个数据库


一旦你定义好了数据库是什么样子,你就会要实现创建和维护数据库及其数据表的方法 . 下面是一些创建和删除一个表格的典型语句 :

代码语言:javascript
复制
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 实现 :

代码语言:javascript
复制
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 的子类实例化:

代码语言:javascript
复制
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

将信息放入一个数据库


通过将一个 ContentValues 对象传入 insert() 方法,来将数据插入一个数据库:

代码语言:javascript
复制
// 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", 那么在没有值的时候框架将不会插入一行 ).

从一个数据库中读取数据


要从数据库读取数据,使用 query() 方法, 向其传入你所选择的过滤条件和想要获取的列. 该方法结合了 insert() 和 update() 的要素, 除了定义了你想要获取的数据的列清单,而不是要插入的数据 . 向你返回的查询结果在一个 Cursor 对象中.

代码语言:javascript
复制
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() 获取到. 例如:

代码语言:javascript
复制
cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);

从数据库中删除信息


要从数据库中删除行,你需要提供识别这些行的选择条件. 数据库API提供了创建能够防止数据库注入的选择条件的机制. 该机制将选择指标分成选择语句和选择参数 . 语句部分定义了要查找的列,同时也允许你结合列测试 . 参数部分是绑定到语句中的测试用的值 . 因为结果不是处理同一个常规的SQL语句,它也就不会受到SQL注入的侵害.

代码语言:javascript
复制
// 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() 内含的values语法内容同delete()的where语法结合了起来.

代码语言:javascript
复制
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);

来源:

http://developer.android.com/training/basics/data-storage/databases.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014/05/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义一个 Schema 和 Contract
  • 使用 SQL Helper 创建一个数据库
  • 将信息放入一个数据库
  • 从一个数据库中读取数据
  • 从数据库中删除信息
  • 更新数据库
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档