使用参考

NoSQLDatabase 提供了一个支持即时同步功能的 NoSQL 数据库; 开发者可以使用 NoSQLDatabase 存储, 查询, 同步 JSON 数据对象。

NoSQLDatabase


表示一个数据库的实例, 用于对数据库进行设置和操作, 以及获取数据节点引用 (NodeReference)所有数据操作需要通过数据节点的引用进行。

Summary


Constructor

Description

NoSQLDatabase(Context context, String accessKey, String namespace, String shardId)

创建一个 namespace 下指定数据空间的数据库实例。

Returns

Public Methods

void

setAccountToken(String token)  设置账号 token, 用于使用账号访问云端资源。

void

setDeviceToken(String token)  设置设备 token, 用于使用设备访问云端资源。

void

goOnline()  将数据库实例状态设置为在线。

NodeReference

getReference(String path)  获取 path 指定节点的引用。

void

close(boolean dropDatabase)  关闭当前数据库实例。

void

setOnDatabaseEventListener(OnDatabaseEventListener listener)  监听数据库发出的事件。

void

enableDebugLog(boolean val)  设置是否启用数据库 debug log。

Constructor


NoSQLDatabase(Context context, String accessKey, String namespace, String shardId)

创建一个 namespace 下指定数据空间的数据库实例。

Parameters

type

Description

context

String

Application context。

accessKey

String

项目关联的网关应用AppKey。

namespace

String

指定要访问 SyncStore 的 namespace。

shardId

String

标示本地不同数据空间的本地数据库, 建议传入数据空间的 id(即账号 id 或设备 id); 如果本地同时存在多个不同数据空间的数据库副本 (如切换账号时), 必须使用不同的 shardId 加以区分, 否则本地不同数据空间的数据会混乱。

Throws

Description

DatabaseException

初始化字段不合法。

注意

说明

应用中同一配置的数据库应当只被创建一次并保持单例, 严格避免重复创建相同配置的数据库实例; 使用不同的 db connection 操作同一个 db 可能出现 db 锁死, 参考 http://www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked不同配置的数据库实例可以共存。

Example

初始化数据库实例

NoSQLDatabase db = new NoSQLDatabase(
    context,
    accessKey, // 项目关联的网关应用AppKey
    namespace, // 在控制台上申请的 namespace
    shardId, // 标示本地不同数据空间的本地数据库, 建议传入数据空间的id (即账id 或设备id); 如果本地同时存在多个不同数据空间的数据库副本(如切换账号时), 必须重新创建数据库并使用不同的 shardId 加以区分, 否则本地不同数据空间的数据会混乱
    endPoint // 服务地址, https:// | http:// 开头
);

Public Methods


setAccountToken(String token)

将当前账号鉴权体系的 token 传给数据库实例, 用于云端资源访问鉴权。

在数据库处于 online 状态时, 设置有效 token 后数据库会开始进行同步token 无效或失效后, 数据库实例会发出 onTokenInvalid 事件, 表示云端资源鉴权失败, 需要开发者进行相处理。

Parameters

type

Description

token

String

账号 token。

setDeviceToken(String token)

将当前设备鉴权体系的 token 传给数据库实例, 用于云端资源访问鉴权。

在数据库处于 online 状态时, 设置有效 token 后数据库会开始进行同步token 无效或失效后, 数据库实例会发出 onTokenInvalid 事件, 表示云端资源鉴权失败, 需要开发者进行相处理。

Parameters

type

Description

token

String

设备 token。

goOnline()

将数据库实例设置为在线模式, 如果网络连通且 token 有效, 任何本地修改都会被立即同步到云端, 云端的修改也会准实时地同步到本地。

goOffline()

将数据库实例设置为离线模式在离线模式下, 本地的变更不会同步到云端, 云端的变更也不会通知到本地。

数据库实例创建之后默认为离线状态, 在调用 goOnline() 之后进入在线状态

getReference(String path)

获取一个节点的引用(NodeReference)所有对节点的读写, 监听数据变更都需要通过节点引用进行。

Parameters

type

Description

path

Stirng

节点的路径, 唯一标识一个 JSON 对象中的节点; 和文件路径相同, 以 “/“ 分隔, 如 a/b 标识 { a:{b:{c:{d:1}}} } 中的 b 节点。

Returns

Description

NodeReference

path 对应的节点的引用。

Throws

Description

DatabaseException

path 为空, path 包含非法字符, path 长度过长, 获取到的 ref 层级超过最大深度。

Example

NodeReference ref1 = db.getReference("/a/b");
NodeReference ref2 = db.getReference("a/b");
NodeReference ref3 = db.getReference("a/b/");
NodeReference ref4 = db.getReference("a//b");
// ref1, ref2, ref3, ref4 指向同一位置

NodeReference ref = db.getReference("a/b/c/d/e/f/g/i/h");
// Error: path 深度超过上限

close(boolean dropDatabase)

关闭当前数据库实例关闭数据库后对 db 实例进行的操作均无效, 对 db 上创建的 ref 进行读写操作均返回错误。

Parameters

type

Description

dropDatabase

boolean

是否删除当前数据库。

setOnDatabaseEventListener(OnDatabaseEventListener listener)

监听数据库发出的事件。

Parameters

type

Description

listener

OnDatabaseEventListener

事件回调。

event 包括:

  • onSyncStart() 同步开始。

  • onSyncFinish(int code) 同步结束, code 标示同步是否成功, 0 为成功。

  • onSyncError(DatabaseException e) 返回同步过程中遇到的错误, 用于开发调试, e.code 为错误码。

  • onTokenInvalid(int code) 表示云端资源鉴权失败, 需要开发者进行相处理, err.code 为错误码; 此时数据库同步停止 (offline); 开发者需要重新获取相应体系的 token 并传给 db。

错误码参考

编号

含义

备注

0

成功

处理成功。

10000

参数为空

必选参数为空。

10001

错误的JSON层级

例如上传的JSON树超过8层。

10002

错误的参数格式

例如上传的JSON格式不正确。

10003

参数错误

例如path错误。

10004

版本错误

同步协议相关。

10005

生成密钥失败

管理平台相关-添加namespace。

10006

token错误

accesstoken或者uuidtoken错误。

10007

认证类型错误

认证类型和namespace不一致。

10008

获取锁失败

并发冲突。

10009

triggerpath存在

管理平台相关-添加trigger。

11001

账号token错误

账号token错误。

11002

设备token错误

设备token错误。

11003

YunOS账号token错误

YunOS账号token错误。

11004

YunOS设备token错误

YunOS设备token错误。

20001

存储数据失败

服务存储数据失败。

20002

获取数据失败

服务获取数据失败。

1

失败

流程出现异常。

Example

NoSQLDatabase db = new NoSQLDatabase(...);

db.setOnDatabaseEventListener(new OnDatabaseEventListener() {
    @Override
    public void onSyncStart() {
        Log.d(TAG, "sync start");
    }

    @Override
    public void onSyncFinish(int code) {
        Log.d(TAG, "sync finish");
        // code 为 0 代表成功
    }

    @Override
    public void onSyncError(DatabaseException e) {
        Log.d(TAG, "sync error: " + e.toString());
        // 返回同步过程中遇到的错误, 用于开发调试
    }

    @Override
    public void onTokenInvalid(int code) {
        // token 无效后同步自动停止, code 反映具体哪个 token 无效
        // 详见上文“错误码参考”中 11XXX 系列错误码
        Log.d(TAG, "token invalid: " + Srting.valueOf(code));

        // 需要重新获取并传入 auth 信息
        db.setXXXToken(XXXToken);
        // 重新继续同步
        db.goOnline();
    }
});

NodeReference


数据节点的引用, 用于对数据节点进行操作, 以及监听本节点数据的变更。

注意

说明

ref 自身不包含任何数据, 只代表数据库中 JSON 结构某一位置的一个引用。

Summary


Returns

Public Methods

NodeReference

copy()  复制一个当前节点的引用对象,节点上的数据视图不会被复制。

NodeReference

child(String path)  根据相对路径获取一个子节点的引用对象。

NodeReference

parent()  获取当前节点父节点的引用对象。

NodeReference

root()  获取根节点的引用对象。

String

path()  获取当前节点引用的全路径。

void

setOnDataChangeListener(OnDataChangeListener l)  监听当前 ref 上的云端数据变更事件。

void

removeOnDataChangeListener()  取消节点引用上的数据变更事件监听。

void

get(GetCallback callback)  获取本节点的数据对象。

void

keys(KeysCallback callback)  获取当前节点下所有 key 的列表。

void

set(JSONObject obj,PutCallback callback)  向本节点写入数据,已经存在的数据会被替换。

void

update(JSONObject obj,PutCallback callback)  向本节点写入新数据,已有数据与新写入的数据合并,重复的数据被新值覆盖(所有写入的数据,无论写入的值是否和之前不同,都会被同步)。

void

updateWithDiff(JSONObject obj, PutCallback callback)  向本节点写入数据,功能与 update 相同,只有新值中与旧值不同 (或旧值不存在) 的部分会被写入(只有值发生变化的部分数据会被同步),性能低于 update。

void

push(JSONObject obj,PutCallback callback)  向节点中写入个 k-v 对,k 的值为自动生成的自增 id,v 的值为传入的 value。

void

delete(String path,PutCallback callback)  从当前节点中删除某个 path。

void

remove(PutCallback callback)  删除本节点的所有数据。

NodeReference

orderByChild(String field)  数据视图-排序条件:查询一层对象节点,按照其中的名为 filed 的子属性的值进行排序。

NodeReference

orderByKey()  数据视图-排序条件:查询一层节点(无论对象节点或值节点),按节点的键名(key 名称进)行排序。

NodeReference

orderByValue()  数据视图-排序条件:查询一层值节点,按照值节点的值进行排序。

NodeReference

limitToFirst(int limit)  数据视图-数量:正序排列,一共返回 limit 个节点。

NodeReference

limitToLast(int limit)  数据视图-数量:倒序排列,一共返回 limit 个节点。

NodeReference

startAt(String value)  数据视图-过滤条件:返回大于或等于指定的 key、value 的节点,具体取决于所选的排序方法。

NodeReference

endAt(String value)  数据视图-过滤条件:返回小于或等于指定的 key、value 的节点,具体取决于所选的排序方法。

NodeReference

equalTo(String value)  数据视图-过滤条件:返回等于指定的 key、value 的节点,具体取决于所选的排序方法。

Public Methods


copy()

复制一个当前节点的引用对象,节点上的数据视图不会被复制。

Returns

Description

NodeReference

复制的引用对象。

child(String path)

根据相对路径获取一个子节点的引用对象。

Parameters

type

Description

path

String

子节点与当前节点的相对路径。

Throws

Description

DatabaseException

path 为空,path 包含非法字符,path 长度过长,获取到的 ref 层级超过最大深度。

Returns

Description

NodeReference

子节点的引用对象。

parent()

获取当前节点父节点的引用对象。

Returns

Description

NodeReference

父节点的引用对象。

root()

获取根节点的引用对象根节点之不能进行写操作 (set,update,push)

Returns

Description

NodeReference

根节点的引用对象。

path()

获取当前节点引用的全路径。

Returns

Description

String

当前节点引用的全路径。

setOnDataChangeListener(OnDataChangeListener l)

监听当前 ref 上的云端数据变更事件只有在注册状态下才能收到云端变更回调,默认为启用注册状态。

Parameters

type

Description

listener

OnDataChangeListener

事件回调。

eventName 包括:

  • onChange(JSONObject newObject, JSONObject conflictObject) 表示接收到云端 ref 中的数据变化或 ref 自身发生变化。

  • newObject 数据变化后 ref 下的数据内容。

  • conflictObject 本次变更的冲突内容,如果本次数据更新没有冲突则无此字段。

注意

说明

事件监听根据监听的范围不同会产生一定的消耗,监听的范围越大,产生的消耗也越大监听事件触发时会返回 ref 下所有数据,请避免在会返回大量数据的 ref 上进行监听,如只关心变化事件,可使用 ref.orderByXXX().limitToFirst() 等数据视图进行过滤以减少数据返回量请保证只对必要的范围进行监听,并且在不需要时及时取消监听。

Example: 数据冲突

t 时刻之前云和端保持同步,数据为:

{
    "a": {
        "b": 1
        "c": 100
    }
}

t+1 时客户端断网,客户端将数据变为:

{
    "a": {
        "b": 2,
        "c": 100
    }
}

云端将数据变为数据为:

{
    "a": {
        "b": 3,
        "c": 100
    }
}

t+2 时刻客户端联网,同步时产生冲突:

ref.setOnDataChangeListener(new OnDataChangeListener() {
    @Override
    public void onChange(JSONObject newObject,JSONObject conflictObject) {
        if (conflictObject != null) {
            // 更新后有冲突
            // newObject 本地更新后的数据(包括成功合并的没有冲突部分的云端数据)
            // conflictObject 冲突部分的云端数据

            JSONObject local = newObject; // {"a": {"b": 2,"c": 100}}
            JSONObject conflicts = conflictObject; // {"a": {"b": 3}}

            // 开发者可选择应用冲突数据的云端版本
            ref.update(conflictObject,null);
        } else {
            // 更新后没有冲突
        }
});

removeOnDataChangeListener()

取消节点引用上的数据变更事件监听取消后数据库接收到云端数据变更后不会向 ref 发出变更事件; 如有数据变更 ref 的事件监听收不到回调。

get(GetCallback callback)

获取本节点下的数据对象如有数据视图,则获取数据视图过滤之后部分的数据,否则获取本节点下全部数据。

注意

说明

get() 会读取并创建数据对象,会占用内存get() 不限制读出的数据量大小,如果读出大量数据,有耗尽内存的风险!

Parameters

type

Description

callback

GetCallback

操作回调。

keys(KeysCallback callback)

获取本节点下所有 key 的列表。

Parameters

type

Description

callback

KeysCallback

操作回调。

set(JSONObject object,PutCallback callback)

向本节点写入数据,已经存在的数据会被替换。

注意

说明

不能在根节点的引用上进行写操作。

Parameters

type

Description

obj

JSONObject

要写入的数据。

callback

PutCallback

操作回调。

update(JSONObject obj,PutCallback callback)

向本节点写入新数据,已有数据与新写入的数据合并,重复的数据被新值覆盖 (所有写入的数据,无论写入的值是否和之前不同,都会被同步)。

注意

说明

不能在根节点的引用上进行写操作。

Parameters

type

Description

obj

JSONObject

要写入的数据。

callback

PutCallback

操作回调。

updateWithDiff(JSONObject obj,PutCallback callback)

向本节点写入数据,功能与 update 相同,只有新值中与旧值不同(或旧值不存在)的部分会被写入(并且只有值发生变化的部分数据会被同步),性能低于 update。

注意

说明

不能在根节点的引用上进行写操作。

Parameters

type

Description

obj

JSONObject

要写入的数据。

callback

PutCallback

操作回调。

push(JSONObject,PutCallback callback)

向节点中写入个 k-v 对,k 的值为自动生成的自增 id,v 的值为传入的 value。

注意

说明

不能在根节点的引用上进行写操作自动生成的 id 以本地时间为基础进行自增, 本地时间的调整可能会破坏 id 的有序性。

Parameters

type

Description

object

JSONObject

要写入的数据。

callback

PutCallback

操作回调。

Example

数据库中有以下内容:

{
    "notes": {
        ...
    }
}
NodeReference ref = db.getReference("notes");
JSONObject note; 
// note 内容为
// {
//    "title": "note1",
//    "content": "my note"
// }
ref.push(note, new PutCallback() {
    @Override
    public void onSuccess() {
        // 数据库内容变为
        // {
        //     "notes": {
        //         ...
        //         "-Kr4cMSWIFQzmEG588Xe": { // 自动生成的 id
        //             "title": "note1",
        //             "content": "my note"
        //         }
        //     }
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

delete(String path, PutCallback callback)

从当前节点中删除某个 path 代表的子节点。

Parameters

type

Description

path

String

要删除的子节点的相对路径。

callback

PutCallback

操作回调。

remove(PutCallback callback)

删除节点自身。

Parameters

type

Description

callback

PutCallback

操作回调。

orderByChild(String field)

数据视图-排序条件:数据视图匹配当前节点对象下所有对象节点的 filed 字段,没有 field 字段的节点或非对象节点不会参与匹配也不会在数据视图中返回如果同时有指定 limit 条件, 则返回由 filed 字段进行排序后 limit 范围内部分的数据集合

此方法可以与 limitToFirst / limitToLast 和 startAt / endAt / equalTo 方法联合使用如不指定 limitToFirst / limitToLast 则默认为 limitToFirst(1024)

注意

说明

排序条件只影响查询时获取的结果范围,不影响结果的有序性不返回值节点。

Parameters

type

Description

field

String

查询的对象中要排序的属性名。

Returns

Description

NodeReference

当前节点引用自身。

Example:

数据库中有以下内容:

{
    "notes": {
        "Fumcjda-cja8dand": {
            "title": "note1",
            "content": "some content",
            "time": 1497506811474
        },
        "adfIead-I9ewniwe": {
            "title": "note2",
            "content": "some content",
            "time": 1497506851057
        },
        ...
        "Moviene-8dna0dJe": {
            "title": "note3",
            "content": "some content",
            "time": 1497506854890
        },
        "Ondafsd-UQiefasd": "this is a value"
    }
}

获取最近的 3 条 notes 的集合数据视图匹配当前节点下所有对象节点中的 time 字段, 没有 time 字段的节点或非对象节点不会参与匹配, 如 "Ondafsd-UQiefasd": "this is a value" 这个值节点不会进入数据视图。

NodeReference ref = db.getReference("notes");
ref.orderByChild("time").limitToLast(3);

注意

说明

排序条件只指定结果包含最近的 3 条数据,但不保证结果中 3 个节点的排列顺序 (因为 Object key 的无序性),如在结果对象上进行 key 遍历,无法保证第一条是 time 最小的一条。

ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // 返回最近三条结果
        // {
        //     "Fumcjda-cja8dand": {
        //         "title": "note1",
        //         "content": "some content",
        //         "time": 1497506811474
        //     },
        //     "adfIead-I9ewniwe": {
        //         "title": "note2",
        //         "content": "some content",
        //         "time": 1497506851057
        //     },
        //     "Moviene-8dna0dJe": {
        //         "title": "note3",
        //         "content": "some content",
        //         "time": 1497506854890
        //     }
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

若使用关系型数据库存储以上数据,每个 note 为一行,以上查询可类比为:

select * from notes order by time limit 3;

orderByKey()

数据视图-排序条件:数据视图指定返回当前节点下所有数据(包括值节点和对象节点)如果指定了排序条件, 则返回由 key 进行排序后 limit 范围内部分的数据集合

此方法可以与 limitToFirst / limitToLast 和 startAt / endAt / equalTo 方法联合使用如不指定 limitToFirst / limitToLast 则默认为 limitToFirst(1024)

注意

说明

排序条件只影响查询时获取的结果范围,不影响结果的有序性不指定排序条件时本条件无意义(仍然返回本节点下所有数据)。

Returns

Description

NodeReference

当前节点引用自身。

Example:

数据库中有以下内容:

{
    "k1": "v1",
    "k2": "v2",
    "k3": "v3",
    "k4": {"k4": "v4"},
    "k5": {"k5": "v5"},
    "k6": {"k6": "v6"},
}

获取本层下按 key 排序的前 4 条数据的集合数据视图匹配当前节点下所有节点中的 key, 返回最大的 4 条的集合。

NodeReference ref = db.getReference("/");
ref.orderByKey().limitToLast(4);
ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // 返回值节点和对象节点
        // {
        //     "k1": "v1",
        //     "k2": "v2",
        //     "k3": "v3",
        //     "k4": {"k4": "v4"}
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

orderByValue()

数据视图-排序条件:数据视图匹配当前节点对象下所有值节点,对象节点不会参与匹配也不会在数据视图中返回如果指定了排序条件,则返回由值节点的值进行排序后 limit 范围内部分的数据集合。

此方法可以与 limitToFirst / limitToLast 和 startAt / endAt / equalTo 方法联合使用如不指定 limitToFirst / limitToLast 则默认为 limitToFirst(1024)

注意

说明

排序条件只影响查询时获取的结果范围,不影响结果的有序性不返回对象节点。

Returns

Description

NodeReference

当前节点引用自身。

Example:

数据库中有以下内容:

{
    "k1": "v1",
    "k2": "v2",
    "k3": "v3",
    "k4": {"k4": "v4"},
    "k5": {"k5": "v5"},
    "k6": {"k6": "v6"},
}

获取本层下按 value 排序的前 4 条数据的集合。

NodeReference ref = db.getReference("/");
ref.orderByValue().limitToLast(4);
ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // 不返回对象节点
        // {
        //     "k1": "v1",
        //     "k2": "v2",
        //     "k3": "v3",
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

limitToFirst(int limit)

数据视图-数量:正序排列,一共返回 limit 个节点。

此方法需要与 orderByChild,orderByKey,orderByValue 方法联合使用,可以与 startAt / endAt / equalTo 方法联合使用。

Parameters

type

Description

limit

int

返回的结果数量。

Returns

Description

NodeReference

当前节点引用自身。

limitToLast(int limit)

数据视图-数量:倒序排列,一共返回 limit 个节点。

此方法需要与 orderByChild,orderByKey,orderByValue 方法联合使用,可以与 startAt / endAt / equalTo 方法联合使用。

Parameters

type

Description

limit

int

返回的结果数量。

Returns

Description

NodeReference

当前节点引用自身。

startAt(String value)

数据视图-过滤条件:过滤 orderBy 中指定的字段,返回大于等于指定的 value 的节点。

此方法需要与 orderByChild,orderByKey,orderByValue 方法联合使用,可以与 limitToFirst / limitToLast 方法联合使用。

Parameters

type

Description

value

String

过滤条件的值。

Returns

Description

NodeReference

当前节点引用自身。

Example:

以下实例展示 orderBy 和过滤条件组合产生的过虑行为。

数据库中有以下内容:

{
    "k1": "v1",
    "k2": "v2",
    "k3": "v3",
    "k4": {"k": "v4"},
    "k5": {"k": "v5"},
    "k6": {"k": "v6"}
}

查询子对象节点中 “k” 字段的值大于等于 “v5” 的

NodeReference ref = db.getReference("/");
ref.orderByChild("k").startAt("v5");

ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // {
        //     "k5": {"k": "v5"},
        //     "k6": {"k": "v6"}
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

查询子节点中 key 的值大于等于 “k3” 的

NodeReference ref = db.getReference("/");
ref.orderByKey().startAt("k3");

ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // {
        //     "k3": "v3",
        //     "k4": {"k": "v4"},
        //     "k5": {"k": "v5"},
        //     "k6": {"k": "v6"}
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

查询子值节点中 value 的值大于等于 “v2” 的

NodeReference ref = db.getReference("/");
ref.orderByValue().startAt("v2");

ref.get(new GetCallback() {
    @Override
    public void onSuccess(JSONObject object) {
        // {
        //     "k2": "v2",
        //     "k3": "v3"
        // }
    }

    @Override
    public void onError(DatabaseException e) {
        // error
    }
});

endAt(String value)

数据视图-过滤条件:过滤 orderBy 中指定的字段,返回小于等于指定的 value 的节点。

此方法需要与 orderByChild,orderByKey,orderByValue 方法联合使用,可以与 limitToFirst / limitToLast 方法联合使用。

Parameters

type

Description

value

String

过滤条件的值。

Returns

Description

NodeReference

当前节点引用自身。

equalTo(String value)

数据视图-过滤条件:过滤 orderBy 中指定的字段,返回等于指定的 value 的节点。

Parameters

type

Description

value

string/number/boolean

过滤条件的值。

Returns

Description

NodeReference

当前节点引用自身。