Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以暂时挂起ORMLite中自动生成的ID吗?_Java_Android_Sqlite_Ormlite - Fatal编程技术网

Java 我可以暂时挂起ORMLite中自动生成的ID吗?

Java 我可以暂时挂起ORMLite中自动生成的ID吗?,java,android,sqlite,ormlite,Java,Android,Sqlite,Ormlite,我正在写的一个小应用程序中使用Android和ORMLite。该应用程序的目标是有一个工作的导入/导出功能,为此我使用简单的XML框架。在某种程度上,一切都很好 情况如下:对象A包含引用对象B的外键,对象B通过外键本身引用对象C。导出数据库非常好。导入工作到,但有一点需要注意,即只要所有对象的ID都是连续的并且从1开始,导入就可以工作。但如果数据库是碎片化的,即我在这里和那里删除了一条记录,那么在导出数据库之后,生成的XML结构中就会出现“漏洞”。示例对象可以是: @DatabaseTable(

我正在写的一个小应用程序中使用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
}
假设我有一个数据库,其中有两个客户(id 1和2),分别持有从1到5和从6到8的订单。导出此文件,然后在干净的数据库中重新导入,效果非常好。但是,如果我删除客户1及其订单并将其导出,则出口商将按原样写入其id,即

<customer id="2">...</customer>
然后他们通过

orderDao.create((Order)o);
问题是create函数忽略了提供的id(不是0),新生成的customer id是1(在一个新的空数据库中)。订单也一样。但由于它们引用id=2的客户,因此它们之间的链接被中断

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

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

致以最良好的祝愿, Todor

支持
@DatabaseField
注释的
allowGenerateDinsert=true
选项,该选项允许将ID已设置的对象插入生成的ID表中。如果ID字段的值为null或默认值(0,…),则数据库将生成ID。这不是所有数据库类型都支持的(例如Derby)。下面是关于这个特定主题的


我确实认为在这里应该做的事情是在内存中构建对象图,在将其中一个对象保存到磁盘之前,将适当的
客户
关联到他们的
订单
对象上。如果将客户读入内存,则读入
顺序
对象,并在每个对象上设置真正的
客户
对象。然后,当您在数据库中创建每个
Customer
对象时,ORMLite会将
id
字段更改为生成的字段,该字段也会在每个
订单中保存的
Customer\u id
字段上进行更改

如果您有大量数据,并且无法一次性将其全部读入内存(或出于其他原因),那么您可以始终构建
映射
,并将
客户
id从映射到数据库中创建后获得的id的XML中保存。然后,在加载
顺序
对象时,可以在外来对象上设置新的已更正id


希望这有帮助。让我了解有关如何读取对象的更多详细信息,我可以给出一个更好的示例,说明如何构建对象图。

好的,是的,我同意在保存任何内容之前在内存中创建所有内容并设置所有对象关系都会起作用,但是这是一个解决方案,只适用于最简单或最小的数据集。它打开了另一个蠕虫:如果数据集是另一个桌面或服务器数据库的一部分,那么重写ID肯定会破坏一切。或者,如果ID用于其他用途,如创建账单或交货通知,而有人需要从备份中恢复,该怎么办?在数据库还原时更改ID是每个自尊的数据库管理员的一个大禁忌…如果您谈论的是数据库还原,我同意更改ID是baaad。我还以为你说的是一个“小型”Android应用程序,它正在从XML中导入可能存在重叠ID的其他记录。若在其他数据库中引用了重叠的ID,那个么就存在其他问题。我的答案的第二部分有用吗?它向您展示了如何使用第二个对象将未生成的ID插入到同一个表中。此外,我在回答中特别指出,在内存中组装对象仅用于少量数据。你真的读了整个答案吗?只是想确定你看到了我的答案@todor的更新。
custDao.create((Customer)x);
orderDao.create((Order)o);