资讯专栏INFORMATION COLUMN

DataBase in Android

sewerganger / 1704人阅读

摘要:这篇文章是我在学习上的课程时写的知识总结可能会有一些内容来自也有一些例子来自的开发文档总结好了想给大家分享如果我学到了新的东西我也会后续更新我们知道如果我们的数据仅仅是存储在变量中的那么其生命周期可能只是和一样长在我们推出之后我们的数据就会

DataBase in Android

这篇文章是我在学习 Udacity 上的 Android 课程时, 写的知识总结.
可能会有一些内容来自 Udacity, 也有一些例子来自 Android 的开发文档.
总结好了想给大家分享, 如果我学到了新的东西, 我也会后续更新

我们知道, 如果我们的数据仅仅是存储在变量中的, 那么其生命周期可能只是和 Activity 一样长, 在我们推出 APP 之后, 我们的数据就会丢失. 我们需要数据持久化(data persistence). 我们可以将数据存储在文件或者数据库中. 这里我们讨论的是数据库的方式.

计算机存储

计算机有两大主要的存储设备, 一类是内存, 一类是外存. 内存(Memory), 是一种临时存储器, 读写速度快, 断电数据丢失, 所以不能长期保存数据. 外存, 包括硬盘, 软盘, 光盘等等, 读写速度慢, 但是可以长期保存数据, 断电不丢失. 我们平时所称的安装 APP, 是安装在外存中, 只有当程序运行的时候, 才会被加载到内存中(也必须被加载到内存中才能运行). 我们在程序中使用的变量, 他们的生命周期是随着程序的结束而结束的, 在程序启动时被创建和使用, 在程序结束时被系统销毁, 所以不能作为长久保存数据的工具.

Android 中的几种不同的数据存储选择

我们这里所讨论的内容, 是将数据存储到我们的 Android 设备中, 不包括存储到云端等方式.

Files, 文件

Shared Preferences

SQLite Databases, SQLite 数据库

Files, 保存到文件中

将保存为文件, 常见的有图片, 音乐, 视频的存储等.

Shared Preferences(首选项)

数据以键值对的形式来保存, (Key - Unique string, Value - Primitive types and Strings), 即包括一个唯一的字符串 key 和其对应的值, 值可以是各种原始数据类型或者是 String.

Shared Preferences 不适合存储大量的用户数据, 适合存储少量的关键的用户信息.

SQLite Databases

SQLLite 是一种数据库, 数据库简单来讲, 是一种有组织的数据结构.

SQLite 的基本组成简单来讲, 可以理解为表, SQLite 数据库由一张张的表来组成.

数据库可以让我们轻松的分享大量相关的结构化数据, 同时, 这些数据可能随着使用而不断增长. 比如我们的通讯录, 里面存储的每一个联系人的各种信息, 可以理解为一张表, 记录各种的属性, 比如姓名, 手机, 邮箱等等. 这些联系人之间, 属性和属性之间是相关的, 他们都是大致相同的格式化数据. 属性之间是相关的, "张三" 的手机号是 "130XXXXXXXX" 而不是其他. 同时, 通讯录还会因为我们的联系人的增多而添加内容, 还可以修改和删除内容. 对于这些数据, 我们可以轻松的检索到我们需要的信息.

SQLite 安装 SQLite

最新版的 MacOS 中已经预装了 SQLite, 打开终端输入 sqlite3, 可以检查是否有 SQLite.

SQL

当我们输入 sqlite3 命令进入 SQLite 之后会出现一下界面.

dcrdeMacBook-Pro:~ Dcr$ sqlite3
SQLite version 3.16.0 2016-11-04 19:09:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>

这里我们可以使用 SQL(Structured query language, 结构化查询语言).

SQLite 中的类型

SQLite 中的 Storage Class:

NULL

INTEGER: 有符号整数

REAL: 浮点数

TEXT: 字符串

BLOB: 原始数据, 比如图片或者二进制数据.

对于 booleans, 我们可以使用 INTEGER 来代替:

0 - false

1 - true

语法

下面介绍 SQL 的基本语法.

CRUD

CRUD 是 Create, Read, Update, Delete 的缩写. 是数据库中的四项重要操作.

CREATE
Create a database

在 SQLite 中, 创建一个新的数据库, 可以在命令行中使用 sqlite3 .db 来创建. 或者在进入 sqlite 之后, 使用 .open .db 来创建.

Create a table

创建一张新的表需要指定表名和列名和对应的数据类型. 语法如下:

CREATE TABLE (
     ,
     ,
    ...
);

上面是创建表的基本语法, 我们创建时, 还可以给每列对应的参数添加属性, 基本的属性有:

PRIMARY KEY: 主键, 每张表只能有一个主键.

AUTOINCREMENT: 添加行时, 该属性自动加一, 可以用于指定每行的 ID.

NOT NULL: 非空, 表示添加行时, 该元素必须有值.

DEFAULT : 默认值, 如果创建时没有提供值, 那么以默认值填充.

INSERT data in a table

向表中添加行:

INSERT INTO  (
    ,
    ,
    ...) VALUES (
    ,
    ,
    ...
);
READ

读操作使用的是 SELECT 关键字, 基本操作如下:

SELECT 
FROM ;

SELECT 后跟的列项可以用 * 表示所有列.

执行上面的操作, 是查询一个表的所有行, 我们要查询我们所需要的行时, 可以使用 WHERE 关键字.

SELECT 
FROM 
WHERE ;

我们还可以指定结果的排序方式, 通过 ORDER BY 关键字.

SELECT 
FROM 
WHERE 
ORDER BY 

ASC: 升序

DESC: 降序

UPDATE

UPDATE 用于更新表中的数据.

UPDATE 
SET  = 
WHERE ;

同样, 使用 WHERE 指定所要修改的行.

DELETE
删除行

删除满足 WHERE 条件的行.

注意: 使用 DELETE 一定要非常小心, 比如, DELETE FROM table_name 就会删除所有行.

DELETE FROM 
WHERE ;
删除表

删除表使用 DROP TABLE 关键字:

DROP TABLE ;
SQLite 中的命令

.shema : 显示创建表的命令.

PRAGMA TABLE_INFO();: 显示表的列信息

SQLite in Android

[Why is a database always represented with a cylinder?](https://stackoverflow.com/que...
)

确定数据库的架构

确定表的名称

每一列数据的名称和数据类型

TABLE_NAME = "pets"

Column name Data types Attributes
_id INTEGER PRIMARY KEY AUTOINCREEMENT
name TEXT NOT NULL
breed TEXT
gender INTEGER NOT NULL DEFAULT 0
weight INTEGER NOT NULL DEFAULT 0
Contract

我们在使用数据库时, 会用到很多的变量, 为了方便和不出错, 我们可以将这些变量多带带拿出来, 这就是 Contract 类.

Contract 类中, 定义了我们将用到的许多常量, 比如, URI, 表名, 列名以及一些有特殊意义的整数值等等. 下面是一个简单的例子: 例子中, 重写了私有的构造函数, 因为我们并不需要该类的对象.

public final class FeedReaderContract {
    // To prevent someone from accidentally instantiating the contract class,
    // make the constructor private.
    private FeedReaderContract() {}

    /* Inner class that defines the table contents */
    public static class FeedEntry implements BaseColumns {
        public static final String TABLE_NAME = "entry";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
    }
}

有了 Contract 类之后, 我们就可以写出我们常用的 SQL 语句了. 比如, 下面就是我们常用的 CREATE TABLEDROP TABLE 语句.

private static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
    FeedEntry._ID + " INTEGER PRIMARY KEY," +
    FeedEntry.COLUMN_NAME_TITLE + " TEXT," +
    FeedEntry.COLUMN_NAME_SUBTITLE + " TEXT)";

private static final String SQL_DELETE_ENTRIES =
    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
通过 SQLHelper 创建数据库

在 Android 中, 数据库默认存储在应用的私有区域的, 这一区域默认情况下其他应用是无法访问的, 所以是安全的.

我们可以使用 SQLiteOpenHelper 类来获取数据库的引用, 此时, 系统会在需要的时候才会执行 creating 和 update 数据库这些费时的操作, 而不是在应用启动的时候, 我们需要做的就是去调用 getWritableDatabase() 或者 getReadableDatabase() 方法.

注意: 因为这样的操作可能是长时间操作, 所以, 务必请在后台线程调用 getWritableDatabase() 或者 getReadableDatabase() 方法.

使用时, 我们可以继承 SQLiteOpenHelper 类重写 onCreate(), onUpgrade(), 和 onOpen() 回调方法, 在需要时, 也可以重写 onDowngrade() 方法. 比如:

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);
    }
}

我们在需要数据库的时候, 使用下面的语句.

FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
在数据库中存入数据

我们在将数据存入数据库中时, 可以使用 ContentValues 对象来进行.

ContentValues 对象就是键值对组, 操作起来也比较简单. 操作步骤如下:

// 1. 获取 SQLiteDatabase 对象
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// 2. 创建值的 map, keys 是列名
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);

// 3. 加入到数据库中去
long newRowId = db.insert(FeedEntry.Table_name, null, values);
从数据库中读取数据 method query()

首先我们可以先了解一下 query() 方法.

SQLiteDatabase.query():

Cursor query (String table,
                String[] columns,
                String selection,
                String[] selectionArgs,
                String groupBy,
                String having,
                String orderBy,
                String limit)
Parameters
table String: 要查询的表
column String[]: 要查询的列的数组。
selection String: 对应 SQL 中的 WHERE 语句部分(不包括 WHERE 本身).
selectionArgs String[], 在 selection 参数中, 可能包含 ? 作为参数的占位符, 在这个参数中给出.
groupBy String: 对应 SQL 语句中的 GROUP BY 语句(不包括 GROUP BY 本身).
having String: 对应 HAVING 语句(不包括 HAVING 本身).
orderBy String: SQL ORDER BY 语句(不包括 ORDER BY 本身)
limit String: 返回的行数, LIMIT 分句的格式
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_SUBTITLE
    };

// Filter results WHERE "title" = "My Title"
String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = { "My Title" };

// How you want the results sorted in the resulting Cursor
String sortOrder =
    FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";

Cursor cursor = 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 对象, 那么什么是 Cursor 呢? Cursor 是查询结果中行的集合.

首先, 顾名思义, Cursor 有一个 position 的指针, 指向的就是当前的行. 行的编号是从 0 开始的, 初始 position = -1.

其工作模式就是, 通过一系列 move 方法, 来选中行, 再通过不同的 get 方法来获取我们需要的数据.

在确定列的时候, 我们需要知道列名, 然后通过 getColumnIndex() 或者 getColumnIndexOrThrow() 来获取 column index. 有了 column index, 我们就可以通过 getInt() getFloat() 等一系列方法来获取具体的数据.

getCount(): 返回 cursor 的行数.

getType(int columnIndex): 返回给定的列的类型

getDouble(int columnIndex) getFloat(int columnIndex) getInt(int columnIndex) getLong(int columnIndex) getString(int columnIndex) getShort(int columnIndex): 返回对应类型的值.


所有的 move 方法返回一个 boolean 值, 表示能否移动到该行.

moveToFirst(): 移动到第一行

moveToLast(): 移动到最后一行

moveToNext(): 移动到下一行

moveToPosition(int position): 移动到指定位置

moveToPrevious(): 移动到前一次移动的行

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/13883.html

相关文章

  • H5 缓存机制浅析 - 移动端 Web 加载性能优化

    摘要:根据标准,到目前为止,一共有种缓存机制,有些是之前已有,有些是才新加入的。首次请求缓存有效期内请求缓存过期后请求一般浏览器会将缓存记录及缓存文件存在本地文件夹中。 腾讯 Bugly 特约作者:贺辉超 1. H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离线存储,这意味着 web ...

    alin 评论0 收藏0
  • H5 缓存机制浅析 - 移动端 Web 加载性能优化

    摘要:根据标准,到目前为止,一共有种缓存机制,有些是之前已有,有些是才新加入的。首次请求缓存有效期内请求缓存过期后请求一般浏览器会将缓存记录及缓存文件存在本地文件夹中。 腾讯 Bugly 特约作者:贺辉超 1. H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性。离线存储(也可称为缓存机制)是其中一个非常重要的特性。H5 引入的离线存储,这意味着 web ...

    Tangpj 评论0 收藏0
  • Kotlin 资源大全

    摘要:联系方式开发交流群扫描二维码添加小编好友,备注,稍后会拉你进群 目录 介绍 官网及文档 中文社区 教程 & 文章 开源库和框架 Demo 其他 介绍 今天凌晨的 Google I/O 上,Google 正式宣布官方支持 Kotlin. 为了让大家更快了解和上手 Kotlin,掘金技术社区为大家整理了这份 Kotlin 资源大全,希望可以帮助大家用最短时间学习 Kotlin. 官...

    VPointer 评论0 收藏0
  • Use SQLite Instead of Local Storage In Ionic Frame

    Switching to object-based data storage can often be tough. If you’re trying to start Phonegap or Ionic Framework development and are coming from native development, the whole local storage concept ca...

    shenhualong 评论0 收藏0
  • Espresso-基于MVP架构,采用RxJava2, Retrofit2, Realm3.0, Z

    Espresso Android App showImg(https://segmentfault.com/img/bVL1hc?w=384&h=384); Espresso is an express delivery tracking app designed with Material Design style, built on MVP(Model-View-Presenter) arch...

    dendoink 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<