我可以暂时中止在ORMLite自动生成的ID? [英] Can I temporarily suspend auto-generated ID in ORMLite?

查看:647
本文介绍了我可以暂时中止在ORMLite自动生成的ID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个小的应用程序,我目前正在写使用的是Android与ORMLite。该应用程序的目的是有一个工作的导入/导出功能,我用简单的XML框架。而一切的伟大工程,到一个点。

I am using Android with ORMLite in a small app I am currently writing. The app aims to have a working Import/Export function, for which I use Simple XML framework. And everything works great, up to a point.

的情况如下:对象A包含一个外键引用对象B,它引用对象C通过外键本身。导出数据库是巨大的。导入作品,用小的警告,即它的工作原理,只要所有物体的ID是连续的,并从1开始,但如果数据库是零散的,也就是我在这里和那里删除的记录,之后我导出数据库,我在生成的XML结构的洞。实例对象可以是:

The situation is as follows: Object A contains a foreign key referencing Object B, which references Object C through a foreign key itself. Exporting a database is great. Importing works to, with a small caveat, namely that it works as long as the IDs of all object are sequential and start from 1. But if the database is fragmented, i.e. I deleted a record here and there, after I export the database, I have "holes" in the generated XML structure. Example objects could be:

@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客户(编号1和2),它通过5和6分别持有1的订单数据库中,通过8导出这个,然后重新导入一个干净的数据库的伟大工程。然而,如果我删除用户1和他们的订单和导出,出口商将填写自己的证件,因为他们,即

Let's say I have a database with 2 customers (id 1 and 2), which hold respectively orders from 1 through 5 and 6 through 8. Exporting this and then re-importing in a clean database works great. If however I delete customer 1 and their orders and export it, the exporter will write their id as they are, i.e.

<customer id="2">...</customer>

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

等。当我将数据导入到一个新的数据库,我会先保存客户对象,通过

etc. When I import the data into a fresh database, I would first save the customer object via

custDao.create((Customer)x);

然后每个订单通过

and then each of their orders via

orderDao.create((Order)o);

的问题是,在创建函数无视提供ID(其不为0)和新生成的ID为客户是1(在一个新鲜的,空的数据库)。相同的数量级。但是因为它们引用的客户id为2,它们之间的链路断开

The problem is that the create function disregards the provided id (which is not 0) and the newly generated id for customer is 1 (in a fresh, empty database). Same for the orders. But since they reference customer with id=2, the link between them is broken.

所以在这个有点啰嗦的解释,这里是我的问题:有没有办法告诉ORMLite承担,而不是覆盖它提供的价值为generatedId现场,并运行它,?我将是美好的,如果万一产生任何异常的create函数发现行已经在表中使用相同的ID,但会继续保存记录,否则... 我曾经想过一个变通的这一点:所有的对象应该是排序通过比较接口ID;排序与要导入的对象ArrayList中;每个对象 - 读应该标识为一个int, - 保存到数据库中使用dao.create, - 如果对象的新的id是不是应该ID不同,通过dao.updateId改变它, - 移动到列表中的下一个对象..不过,这似乎过于繁琐,容易出错:如果什么创建方法试图生成一个ID,您只需重新分配给具有updateId一个previous对象

So after this somewhat long-winded explanation, here is my question: Is there a way to tell ORMLite to take the provided value for a generatedId field and run with it, instead of overwriting it? I would be OK, if any Exception is generated in case the create function finds row already in the table with the same ID, but would proceed with saving the record otherwise... I have thought of a work-around for this: all the objects should be sortable by ID using the Comparator interface; sort the ArrayList with objects to be imported; for each object - read supposed id into an int, - save to database using dao.create, - if the object's new id is different than supposed id, change it via dao.updateId, - move to the next object in the list... But that seems too cumbersome and error-prone: What if the create method tries to generate an id, which you just re-assigned to a previous object with updateId?

我不相信我的情况非常罕见,没有人以前也遇到过这一点。我想AP preciate的解决方案!

I don't believe my situation is so rare, that no one has encountered this before. I would appreciate a solution!

最好的问候, 托多尔

推荐答案

ORMLite 支持 allowGeneratedIdInsert = TRUE 选项 @DatabaseField 注释,允许已设置成产生-ID表中的ID插入的对象。如果ID字段的值为空值或默认值(0,...),那么该数据库将生成的ID。这是不是所有的数据库类型(德比为例)的支持。这里是另一个讨论这个特定的主题。

ORMLite supports a allowGeneratedIdInsert=true option to @DatabaseField annotation that allows inserting of an object with the ID already set into a generated-id table. If the value of the ID field is null or default value (0, ...) then the database will generate the ID. This is not supported by all database types (Derby for example). Here's another discussion about this specific topic.

我认为正确的事情做的,是建立在内存中的对象图,关联起来的正确客户在他们订单对象的的节省了他们的磁盘。如果你读你的客户到内存中,然后读了订单对象和设置真实客户对象的每一个。当您然后在数据库中创建的每个客户对象,ORMLite将改变 ID 场产生的其中一个将改变它保存在 CUSTOMER_ID 字段中的每个订单

I do think the proper thing to do here is to build your object graph in memory, associating the proper Customer on their Order objects before saving an of them to disk. If you read your Customers into memory, then read in the Order objects and set the real Customerobject on each one. When you then create each Customer object in the database, ORMLite will change the id field to the generated one which would change it on the customer_id field saved in each Order as well.

如果你有大量的数据,并不能读这一切到内存中的一个(或某些其他原因),那么你总是可以建立一个地图&LT;整数,整数GT; 和保存客户 ID从映射到ID,你让你在数据库中创建后的XML。然后,当你在订单加载对象,可以在异物上设置新的校正ID。

If you have a ton of data and can't read it all into memory at one (or for some other reason) then you could always build a Map<Integer,Integer> and save the Customer id from the XML mapped to the id you get after you create it in the database. Then when you load in the Order objects you can set the new corrected id on the foreign object.

希望这有助于。让我知道了一些关于你是如何看的对象,我可以给如何构建对象图一个更好的例子更多细节。

Hope this helps. Let me know some more details about how you are reading in the objects and I can give a better example of how to build the object graph.

这篇关于我可以暂时中止在ORMLite自动生成的ID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆