title: 数据操作

本篇文档介绍如何进行数据操作,分为写入,更新和删除数据。

数据操作包含以下七种方法:

方法 说明
setValue() 向指定 节点 写入数据。若此节点已存在数据,会覆盖原有数据。
setPriority() 设置节点优先级。
setValue(value,priority) 向指定节点写入数据并且设置该节点优先级。
push() 向指定节点添加 子节点。子节点的 key 自动生成并保证唯一。
removeValue() 删除指定节点。
updateChildren() 更新指定子节点。
runTransaction() 并发操作时保证数据一致性。

写入数据

setValue() 方法用于向指定节点写入数据。此方法会先清空指定节点,再写入数据。

setValue() 方法可设置回调方法来获取操作的结果。

例如,向 Jobs 节点下写入 full_namegender

  1. // 初始化
  2. WilddogOptions options = new WilddogOptions.Builder().setSyncUrl("https://docs-examples.wilddogio.com").build();
  3. WilddogApp.initializeApp(this, options);
  4. // 获取 SyncReference 实例
  5. SyncReference ref = WilddogSync.getInstance().getReference("web/saving-data/wildblog/users");
  6. // 创建 Map 对象
  7. HashMap<String, Object> user = new HashMap<>();
  8. user.put("full_name", "Steve Jobs");
  9. user.put("gender", "male");
  10. // child() 用来定位到某个节点。
  11. ref.child("Jobs").setValue(user);

设置回调方法:

  1. ref.child("Jobs").setValue(user, new SyncReference.CompletionListener() {
  2. @Override
  3. public void onComplete(SyncError error, SyncReference ref) {
  4. if (error != null) {
  5. Log.d("error", error.toString());
  6. } else {
  7. Log.d("success", "setValue success");
  8. }
  9. }
  10. });

设置节点优先级

setPriority(priority) 方法用于设置节点的优先级。

Wilddog Sync 支持为每个节点设置优先级(priority),用于实现节点按 优先级排序。优先级是节点的隐藏属性,默认为 null。

例如,设置user节点的优先级为100:

  1. ref.child("user").setPriority(100);

更多使用,请参考 setPriority(priority)

写入数据并设置节点优先级

setValue(value,priority) 方法用于向指定节点写入数据并且设置该节点优先级。

例如,写入 jack 的姓名并且设置优先级为100:

  1. WilddogSync.getInstance().getReference("full_name").setValue("Jack",100,new SyncReference.CompletionListener() {
  2. @Override
  3. public void onComplete(SyncError error, SyncReference ref) {
  4. if (error != null) {
  5. Log.d("error", error.toString());
  6. } else {
  7. Log.d("success", "setValue success");
  8. }
  9. }
  10. });

追加子节点

push() 方法向任意节点添加子节点。新增子节点的 key 自动生成并保证唯一。 新增子节点的 key 基于时间戳和随机算法生成,并可以按照时间先后进行排序。

例如,追加子节点到 posts 节点:

  1. SyncReference postsRef = ref.child("messages");
  2. HashMap<String, Object> aNews = new HashMap<>();
  3. aNews.put("full_name", "Steve Jobs");
  4. aNews.put("message", "Think difference");
  5. postsRef.push().setValue(aNews);
  6. HashMap<String, Object> anotherNews = new HashMap<>();
  7. anotherNews.put("full_name", "Bill Gates");
  8. anotherNews.put("message", "Hello World");
  9. postsRef.push().setValue(anotherNews);

产生的数据如下:

  1. {
  2. "messages": {
  3. "-JRHTHaIs-jNPLXO": {
  4. "full_name" : "Steve Jobs",
  5. "message" : "Think difference"
  6. },
  7. "-JRHTHaKuITFIhnj": {
  8. "full_name" : "Bill Gates",
  9. "message" : "Hello World"
  10. }
  11. }
  12. }

更新数据

updateChildren() 方法用于更新指定子节点。

updateChildren() 方法支持多路径更新。可以只调用一次方法更新多个路径的数据。

例如,更新 Jobs 的个人信息:

  1. //原数据如下
  2. {
  3. "Jobs": {
  4. "full_name" : "Steve Jobs",
  5. "gender" : "male"
  6. }
  7. }
  1. // 只更新 gracehop 的 nickname
  2. SyncReference hopperRef = ref.child("Jobs");
  3. HashMap<String, Object> user = new HashMap<>();
  4. user.put("full_name", "Tim Cook");
  5. hopperRef.updateChildren(user);

例如,同时更新 b 节点下的 d 和 x 节点下的 z:

  1. //原数据如下
  2. {
  3. "a": {
  4. "b": {
  5. "c": "cc",
  6. "d": "dd"
  7. },
  8. "x": {
  9. "y": "yy",
  10. "z": "zz"
  11. }
  12. }
  13. }

正确示例:

  1. HashMap<String, Object> map = new HashMap<>();
  2. map.put("b/d", "updateD");
  3. map.put("x/z", "updateZ");
  4. ref.updateChildren(map);

错误示例:

  1. // 错误的多路径更新写法,会覆盖原有数据
  2. Map<String,Map<String,String>> map = new HashMap<>();
  3. Map<String,String> bMap = new HashMap<>();
  4. Map<String,String> xMap = new HashMap<>();
  5. map.put("b", bMap.put("d","updateD");
  6. map.put("x", xMap.put("z","updateZ");
  7. ref.updateChildren(map);

删除数据

removeValue() 方法用于删除指定节点。

  1. HashMap<String, Object> map = new HashMap<>();
  2. map.put("full_name", "Steve Jobs");
  3. map.put("gender", "male");
  4. ref.setValue(map);
  5. //删除上面写入的数据
  6. ref.removeValue();

提示:

如果某个节点的 value 为 null ,云端会直接删除该节点。

事务处理

runTransaction() 方法用于并发操作时保证数据一致性。

例如,在实现多人点赞功能时,多人同时写入评分会产生覆盖,导致最终结果不准确。使用 runTransaction()方法可以避免这种情况:

  1. SyncReference upvotesRef = WilddogSync.getInstance().getReference("web/saving-data/wildblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes");
  2. upvotesRef.runTransaction(new Transaction.Handler() {
  3. public Transaction.Result doTransaction(MutableData currentData) {
  4. if(currentData.getValue() == null) {
  5. currentData.setValue(1);
  6. } else {
  7. currentData.setValue((Long) currentData.getValue() + 1);
  8. }
  9. return Transaction.success(currentData);
  10. // 也可以这样中止事务 Transaction.abort()
  11. }
  12. public void onComplete(SyncError error, boolean committed, DataSnapshot currentData) {
  13. // 事务完成后调用一次,获取事务完成的结果
  14. }
  15. });

注意:

回调方法的返回值可能为空,需要进行相应的处理。

更多使用,请参考 runTransaction()