我在我目前正在编写的一个小应用程序中使用 Android 和 ORMLite。该应用程序的目标是具有有效的导入/导出功能,为此我使用简单的 XML 框架。在某种程度上,一切都运转良好。
情况如下:对象 A 包含引用对象 B 的外键,对象 B 通过外键本身引用对象 C。导出数据库很棒。导入工作,有一个小警告,即只要所有对象的 ID 都是连续的并且从 1 开始,它就可以工作。但是如果数据库是碎片化的,即我在导出数据库后到处删除了一条记录,我在生成的 XML 结构中存在“漏洞”。示例对象可以是:
@DatabaseTable("orders")
public class Order {
@DatabaseField(generatedId = true)
private int _id;
@DatabaseField(columnName="date")
private Date _date;
@DatabaseField(columnName="cost")
private double _cost;
@DatabaseField(foreign = true, columnName="customer_id")
private Customer _customer;
// ... more fields, getters and setters
}
@DatabaseTable("customers")
public class Customer {
@DatabaseField(generatedId = true);
private int _id;
@DatabaseField
private String _name;
// ... more fields, getters and setters
}
假设我有一个包含 2 个客户(id 1 和 2)的数据库,分别保存从 1 到 5 和 6 到 8 的订单。导出该数据库然后重新导入到干净的数据库中效果很好。但是,如果我删除客户 1 及其订单并将其导出,导出商将按原样写入其 ID,即
<customer id="2">...</customer>
and
<order id="6">...</order>
<order id="7">...</order>
<order id="8">...</order>
<order id="9">...</order>
等等。当我将数据导入新数据库时,我首先通过以下方式保存客户对象
custDao.create((Customer)x);
然后他们的每个订单都通过
orderDao.create((Order)o);
问题是创建函数忽略了提供的 id(不是 0),而新生成的客户 id 是 1(在新的空数据库中)。订单也一样。但由于他们引用了 id=2 的客户,因此他们之间的链接被破坏了。
因此,在这个有点冗长的解释之后,我的问题是:有没有办法告诉 ORMLite 获取 generatedId 字段提供的值并使用它运行,而不是覆盖它?如果创建函数发现表中已经存在具有相同 ID 的行,如果生成任何异常,我会没问题,但会继续保存记录,否则...
我想到了一个解决方法:所有对象都应该可以使用 Comparator 接口按 ID 排序;使用要导入的对象对 ArrayList 进行排序;对于每个对象 - 将假定的 id 读入 int, - 使用 dao.create 保存到数据库, - 如果对象的新 id 与假定的 id 不同,则通过 dao.updateId 更改它, - 移动到列表中的下一个对象。但这似乎太麻烦而且容易出错:如果 create 方法尝试生成一个 id,而您刚刚使用 updateId 将其重新分配给以前的对象,该怎么办?
我不相信我的情况如此罕见,以至于没有人遇到过这种情况。我希望有一个解决方案!
此致,
托多尔