我正在使用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重新分配给一个前一个对象怎么办?
我不相信我的情况如此罕见,以前没有人遇到过这种情况。我很感激解决方案!
祝你好运, 托多尔
答案 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。
希望这会有所帮助。让我知道有关如何阅读对象的更多细节,我可以提供一个更好的示例来说明如何构建对象图。