将数据从 dataSnapshot 解析为 class 是如何工作的?
How does Parsing data from dataSnapshot into a class work?
我曾经使用像这样的地图来解析 dataSnapshots Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
但是当我在 YouTube 上观看教程时,我看到有人像这样使用 class 解析 dataSnapshot User user = dataSnapshot.getValue(User.class);
,现在我有很多问题。
这是如何运作的?
我的意思是,如果 class 用户的成员与快照中的成员不同,会不会给我们带来错误?
例如
snapshot:
-User
|-Name:jojo
|-Age:19
User Class fields:
boolean a;
float x;
int c;
如果 class 用户的字段顺序与快照中的字段顺序不同且大小写不同,或者如果 class 缺少一个字段怎么办?
第二个问题的例子:
snapshot:
-User
|-Name:jojo
|-Age:19
User Class fields:
int age;
String name;
我已阅读 firebase 文档 https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#getValue(java.lang.Class)
但它没有回答我的两个问题它只是说 class 必须有一个空构造函数和每个字段 getter
编辑:
snapshot:
-User
|-Followers
|-id:xxxxxx
|-id:xxxxxx
|-Name:jojo
|-Age:19
User Class fields:
int age;
String name;
Firebase 尝试使用 JavaBean 命名约定在来自数据库的 JSON 数据中的属性与您的 class 中的属性之间进行映射。映射到数据快照的最简单 class 是:
public static class User {
public String Name;
public long Age;
}
这个class对于数据库中的每个属性都有一个public字段,编译器会生成一个默认的no-argument构造函数,这就是Firebase所需要的以便为数据创建 User
个对象。
更常见的模式是为属性创建 getter and/or setter。对于您的两个属性的所有这些,您将获得:
public static class User {
String Name;
long Age;
public String getName() { return Name }
public void getName(String name) { Name = name }
public long getAge() { return Age }
public void setSage(long age) { Age = age }
}
现在有了这些,字段本身不再需要 public,如果需要,我们可以在 get 和 set 方法中做额外的工作。但是属性的名称现在将由那些使用 JavaBean 命名转换的 getter 和 setter 确定,这导致属性 name
和 age
的大小写与数据库中的不同。
要解决这个问题,您可以在代码中提供注释,说明每个字段的数据库属性是什么:
public static class User {
String Name;
long Age;
@PropertyName("Name")
public String getName() { return Name }
@PropertyName("Name")
public void getName(String name) { Name = name }
@PropertyName("Age")
public long getAge() { return Age }
@PropertyName("Age")
public void setSage(long age) { Age = age }
}
现在 Firebase 映射器将读取 PropertyName
注释,并能够再次在数据库中的数据和对象中的数据之间正确映射。
如果您的 class 具有比数据库中的数据更多的属性(因此 public 字段或 getters/setters),则当它从数据库中读取数据时,这些属性将保持未填充状态.写入数据库时,会将附加属性写入数据库。
如果你想阻止这种情况,你可以使用 @IgnoreExtraProperties
annotation.
另见:
我曾经使用像这样的地图来解析 dataSnapshots Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
但是当我在 YouTube 上观看教程时,我看到有人像这样使用 class 解析 dataSnapshot User user = dataSnapshot.getValue(User.class);
,现在我有很多问题。
这是如何运作的?
我的意思是,如果 class 用户的成员与快照中的成员不同,会不会给我们带来错误?
例如
snapshot:
-User
|-Name:jojo
|-Age:19
User Class fields:
boolean a;
float x;
int c;
如果 class 用户的字段顺序与快照中的字段顺序不同且大小写不同,或者如果 class 缺少一个字段怎么办?
第二个问题的例子:
snapshot:
-User
|-Name:jojo
|-Age:19
User Class fields:
int age;
String name;
我已阅读 firebase 文档 https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#getValue(java.lang.Class) 但它没有回答我的两个问题它只是说 class 必须有一个空构造函数和每个字段 getter
编辑:
snapshot:
-User
|-Followers
|-id:xxxxxx
|-id:xxxxxx
|-Name:jojo
|-Age:19
User Class fields:
int age;
String name;
Firebase 尝试使用 JavaBean 命名约定在来自数据库的 JSON 数据中的属性与您的 class 中的属性之间进行映射。映射到数据快照的最简单 class 是:
public static class User {
public String Name;
public long Age;
}
这个class对于数据库中的每个属性都有一个public字段,编译器会生成一个默认的no-argument构造函数,这就是Firebase所需要的以便为数据创建 User
个对象。
更常见的模式是为属性创建 getter and/or setter。对于您的两个属性的所有这些,您将获得:
public static class User {
String Name;
long Age;
public String getName() { return Name }
public void getName(String name) { Name = name }
public long getAge() { return Age }
public void setSage(long age) { Age = age }
}
现在有了这些,字段本身不再需要 public,如果需要,我们可以在 get 和 set 方法中做额外的工作。但是属性的名称现在将由那些使用 JavaBean 命名转换的 getter 和 setter 确定,这导致属性 name
和 age
的大小写与数据库中的不同。
要解决这个问题,您可以在代码中提供注释,说明每个字段的数据库属性是什么:
public static class User {
String Name;
long Age;
@PropertyName("Name")
public String getName() { return Name }
@PropertyName("Name")
public void getName(String name) { Name = name }
@PropertyName("Age")
public long getAge() { return Age }
@PropertyName("Age")
public void setSage(long age) { Age = age }
}
现在 Firebase 映射器将读取 PropertyName
注释,并能够再次在数据库中的数据和对象中的数据之间正确映射。
如果您的 class 具有比数据库中的数据更多的属性(因此 public 字段或 getters/setters),则当它从数据库中读取数据时,这些属性将保持未填充状态.写入数据库时,会将附加属性写入数据库。
如果你想阻止这种情况,你可以使用 @IgnoreExtraProperties
annotation.
另见: