数据模型更新
2024年6月27日14:49:07 ObjectBox - 数据模型更新
- UIDs
- 重命名实体和属性
- Java/Kotlin和Dart的操作方法与示例
- Python的操作方法与示例
- 更改属性类型
- 操作方法与示例
数据模型更新
如何在ObjectBox中重命名实体和属性、更改属性类型。 ObjectBox - 数据模型更新 ObjectBox主要自动管理其数据模型(模式)。数据模型由你定义的实体类来定义。当你添加或删除实体或实体的属性时,ObjectBox会处理这些更改,无需你采取进一步行动。 对于其他更改,如重命名或更改类型,ObjectBox需要额外信息来使事情明确。这是通过设置唯一ID(UIDs)作为注释来完成的,如下所示。
UIDs
ObjectBox通过为实体和属性分配唯一ID(UIDs)来跟踪它们。所有这些UIDs都存储在一个文件中,对于Java和Kotlin是“objectbox-models/default.json”,对于Dart是“lib/objectbox-model.json”,你应该将其添加到版本控制系统(例如git)中。如果你感兴趣,我们有关于UIDs和概念的详细文档。但让我们继续了解如何重命名实体或属性。 简而言之:要进行与UID相关的更改,在实体或属性上添加“@Uid”注释(Java、Kotlin)或“@Entity(uid: 0)/@Property(uid: 0)”(Dart),然后构建项目以获取进一步的说明。对要更改的每个实体或属性重复此操作。
重命名实体和属性
那么为什么我们需要那个UID注释呢?如果你只是重命名一个实体类,ObjectBox只会看到旧实体消失了,而有一个新实体可用。这可以有两种解释:
- 旧实体被删除,应添加一个新实体,旧数据被丢弃。这是ObjectBox的默认行为。
- 实体被重命名,旧数据应被重新使用。 所以要告诉ObjectBox进行重命名而不是丢弃旧实体和数据,你需要确保它知道这是同一个实体而不是一个新实体。你通过将内部UID附加到实体上来做到这一点。 对于属性也是如此。 现在让我们逐步了解如何做到这一点。如果你想重命名一个属性,过程是相同的:
Java/Kotlin和Dart的操作方法与示例
步骤1:向要重命名的实体/属性添加一个空UID: Java/Kotlin:
@Entity
@Uid
public class MyName {... }
Dart:
@Entity(uid: 0)
class MyName {... }
步骤2:构建项目(在Dart中,运行“pub run build_runner build”)。构建将失败,并显示一条错误消息,其中给出了实体/属性的当前UID: Java/Kotlin:
error: [ObjectBox] UID操作对于实体"MyName":
[重命名]使用@Uid(6645479796472661392L)应用当前UID -
[更改/重置]使用@Uid(4385203238808477712L)应用新UID
在"MyName"上找到@Entity(uid: 0) - 你可以选择以下操作之一:
[重命名]使用@Entity(uid: 6645479796472661392)应用当前UID
[更改/重置]使用@Entity(uid: 4385203238808477712)应用新UID
Dart:
error: [ObjectBox] UID操作对于实体"MyName":
[重命名]使用@Entity(uid: 6645479796472661392)应用当前UID -
[更改/重置]使用@Entity(uid: 4385203238808477712)应用新UID
在"MyName"上找到@Entity(uid: 0) - 你可以选择以下操作之一:
[重命名]使用@Entity(uid: 6645479796472661392)应用当前UID
[更改/重置]使用@Entity(uid: 4385203238808477712)应用新UID
步骤3:将错误消息中[重命名]部分的UID应用于你的实体/属性: Java/Kotlin:
@Entity
@Uid(6645479796472661392L)
public class MyName {... }
Dart:
@Entity(uid: 6645479796472661392)
class MyName {... }
步骤4:最后要做的是在语言级别进行实际重命名(Java、Kotlin等): Java/Kotlin:
@Entity
@Uid(6645479796472661392L)
public class MyNewName {... }
Dart:
@Entity(uid: 6645479796472661392)
class MyNewName {... }
步骤5:再次构建项目,现在应该成功。你现在可以按预期使用重命名后的实体/属性,并且所有现有数据仍将存在。 重复上述步骤以重命名另一个实体或属性。 注意:你也可以在引言中提到的模型JSON中找到实体/属性的UID,而不是执行上述操作。在重命名实体/属性之前,你可以自己将UID值添加到注释中,并跳过ObjectBox为你打印UID的中间错误。在重命名多个属性时,这可能会更快。
Python的操作方法与示例
由于在Python中没有构建步骤,重命名实体的步骤不同。假设我们要将实体“MyName”重命名为“MyNewName”:
@Entity()
class MyName:
id = Id
some_property = Int
步骤1:找出实体“MyName”的UID:
print(MyName._uid)
# 6645479796472661392
步骤2:将“MyName”重命名为“MyNewName”并显式指定旧UID:
@Entity(uid=6645479796472661392)
class MyNewName:
id = Id
some_property = Int
这使得Objectbox能够将旧实体与新实体关联起来,并保留持久化数据。如果你不指定旧UID,Objectbox将丢弃旧数据,并向模式中添加一个名为“MyNameName”的全新实体。
更改属性类型
ObjectBox不支持将现有属性数据迁移到新类型。你必须自己处理此问题,例如,保留旧属性并添加一些迁移逻辑。 更改属性类型有两种解决方案:
- 添加一个具有不同名称的新属性(仅当属性尚未有“@Uid”注释时才有效):
// 旧:
String year;
// 新:
int yearInt;
- 为属性设置一个新UID,以便ObjectBox将其视为新属性。让我们逐步了解如何做到这一点:
操作方法与示例
步骤1:向要更改类型的属性添加“@Uid”注释: Java/Kotlin:
@Uid
String year;
Dart:
@Property(uid: 0)
String year;
步骤2:构建项目。构建将失败,并显示一条错误消息,其中给出了新创建的UID值: Java/Kotlin:
error: [ObjectBox] UID操作对于属性"MyEntity.year":
[重命名]使用@Uid(6707341922395832766L)应用当前UID -
[更改/重置]使用@Uid(9204131405652381067L)应用新UID
在"year"上找到@Property(uid: 0) - 你可以选择以下操作之一:
[重命名]使用@Property(uid: 6707341922395832766)应用当前UID
[更改/重置]使用@Property(uid: 9204131405652381067)应用新UID
Dart:
error: [ObjectBox] UID操作对于属性"MyEntity.year":
[重命名]使用@Property(uid: 6707341922395832766)应用当前UID -
[更改/重置]使用@Property(uid: 9204131405652381067)应用新UID
在"year"上找到@Property(uid: 0) - 你可以选择以下操作之一:
[重命名]使用@Property(uid: 6707341922395832766)应用当前UID
[更改/重置]使用@Property(uid: 9204131405652381067)应用新UID
步骤3:将[更改/重置]部分的UID应用于你的属性: Java/Kotlin:
@Uid(9204131405652381067L)
int year;
Dart:
@Property(uid: 9204131405652381067)
String year;
步骤4:再次构建项目,现在应该成功。你现在可以在实体中使用该属性,就像它是一个新属性一样。 重复上述步骤以更改另一个属性的类型。