我可以暂时在ORMLite中暂停自动生成的ID吗?

时间:2011-03-07 06:44:08

标签: java android sqlite ormlite

我正在使用Android与ORMLite在我正在编写的小应用程序中。该应用程序旨在具有可用的导入/导出功能,我使用简单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,你刚刚用updateId重新分配给一个前一个对象怎么办?

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

祝你好运, 托多尔

1 个答案:

答案 0 :(得分:2)

ORMLite支持allowGeneratedIdInsert=true注释的@DatabaseField选项,该注释允许插入已将ID设置为generate-id表的对象。如果ID字段的值为null或默认值(0,...),则数据库将生成ID。所有数据库类型(例如Derby)都不支持此功能。以下是关于此特定主题的another discussion


我认为在这里做的正确的事情是在内存中构建对象图,在<{1}}对象之前将正确的 Customer关联起来将它们保存到磁盘。如果您将客户读入内存,请阅读Order个对象并在每个对象上设置真正的Order对象。然后,当您在数据库中创建每个Customer对象时,ORMLite会将Customer字段更改为生成的字段,该字段会在每个id中保存的customer_id字段中将其更改为好。

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

希望这会有所帮助。让我知道有关如何阅读对象的更多细节,我可以提供一个更好的示例来说明如何构建对象图。