0

我在我目前正在编写的一个小应用程序中使用带有 ORMLite 的 Android。该应用程序旨在拥有一个有效的导入/导出功能,为此我使用简单的 XML 框架。在某种程度上,一切都很好。

情况如下:对象A包含一个引用对象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>

<order id="6">...</order>
<order id="7">...</order>
<order id="8">...</order>
<order id="9">...</order>

等当我将数据导入一个新的数据库时,我会首先通过以下方式保存客户对象

custDao.create((Customer)x);

然后他们的每个订单通过

orderDao.create((Order)o);

问题是 create 函数忽略了提供的 id(不是 0),并且新生成的 customer id 是 1(在一个新的空数据库中)。订单也一样。但是由于他们引用了 id=2 的客户,所以他们之间的链接被破坏了。

所以在这个有点冗长的解释之后,这是我的问题:有没有办法告诉 ORMLite 为 generateId 字段获取提供的值并使用它运行,而不是覆盖它?如果创建函数在表中找到具有相同 ID 的行已经生成任何异常,我会没问题,但会继续保存记录,否则......我已经想到了一个解决方法:所有对象应该可以使用 Comparator 接口按 ID 排序;使用要导入的对象对 ArrayList 进行排序;对于每个对象 - 将假定 id 读入 int, - 使用 dao.create 保存到数据库, - 如果对象的新 id 与假定 id 不同,则通过 dao.updateId 更改它, - 移动到列表中的下一个对象.. . 但这似乎太麻烦且容易出错:如果create方法试图生成一个id怎么办,

我不相信我的情况如此罕见,以前没有人遇到过这种情况。我会很感激一个解决方案!

最好的问候,托多

4

1 回答 1

2

ORMLite支持注释allowGeneratedIdInsert=true选项@DatabaseField,允许将 ID 已设置的对象插入到生成的 ID 表中。如果 ID 字段的值为 null 或默认值 (0, ...),则数据库将生成 ID。并非所有数据库类型都支持此功能(例如 Derby)。这是关于这个特定主题的另一个讨论。


我认为正确的做法是在内存中构建你的对象图,在将它们 中的一个保存到磁盘之前Customer将它们关联到它们的Order对象上。如果您将客户读入内存,则读入对象并在每个对象上设置真实对象。然后,当您在数据库中创建每个对象时,ORMLite 会将字段更改为生成的字段,这也会更改每个对象中保存的字段。OrderCustomerCustomeridcustomer_idOrder

如果您有大量数据并且无法一次将其全部读入内存(或出于其他原因),那么您始终可以构建一个并将XML 中的 idMap<Integer,Integer>保存到您在创建它后获得的 id 中Customer数据库。然后,当您加载Order对象时,您可以在外来对象上设置新的更正 ID。

希望这可以帮助。让我知道更多关于你如何阅读对象的细节,我可以给出一个更好的例子来说明如何构建对象图。

于 2011-03-07T14:37:51.237 回答