2011-03-07 35 views
0

我正在使用Android的ORMLite在我正在寫的一個小應用程序。該應用程序旨在有一個工作的導入/導出功能,我使用簡單的XML框架。而且一切都很好,直到一點。我可以暫時掛起ORMLite中的自動生成的ID嗎?

情況如下:對象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,IE

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

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

等等。當我將數據導入到新的數據庫,我會先通過

保存通過

custDao.create((Customer)x); 

,然後每一個他們的訂單的客戶對象0

orderDao.create((Order)o); 

問題是create函數忽略提供的id(不是0),而新生成的客戶id是1(在新鮮的空數據庫中)。訂單也一樣。但是因爲他們引用id = 2的客戶,他們之間的鏈接就被打破了。

因此,在這個有點冗長的解釋之後,這裏是我的問題:有沒有辦法告訴ORMLite爲generatedId字段提供值並運行它,而不是覆蓋它?如果在創建函數發現已經在表中具有相同ID的行的情況下生成任何異常,但會繼續保存該記錄,否則我會好的... 我想到了解決這個問題的辦法:所有對象應該使用比較器接口通過ID進行排序;將ArrayList與要導入的對象進行排序;對於每個對象 - 將假設的ID讀入一個int, - 使用dao.create保存到數據庫, - 如果對象的新ID與假定ID不同,請通過dao.updateId更改它, - 移至列表中的下一個對象。 。但是這看起來太麻煩,容易出錯:如果create方法試圖生成一個id,而你剛剛使用updateId重新分配給以前的對象,該怎麼辦?

我不相信我的情況非常罕見,以前沒有人遇到過這種情況。我將不勝感激解決方案!

此致 託多爾

+0

只是想確保你看到了我的答案@todor的更新。 – Gray 2011-10-20 17:04:35

回答

2

ORMLite支持allowGeneratedIdInsert=true選項@DatabaseField註釋允許與已經設置成產生-ID表中的ID插入對象的。如果ID字段的值爲空或默認值(0,...),則數據庫將生成該ID。這不是所有數據庫類型都支持的(例如Derby)。這裏是關於這個特定主題的another discussion


我覺得在這裏做正確的事情是建立你的對象圖在內存中,關聯的適當Customer他們Order對象之前節省了他們的磁盤。如果您將客戶讀入內存,請閱讀Order對象,並在每個對象上設置實際的Customer對象。然後,當您在數據庫中創建每個對象時,ORMLite會將id字段更改爲生成的字段,並在每個Order中保存的customer_id字段中更改它。

如果你有大量的數據,並且無法將它全部讀入內存(或者出於某種其他原因),那麼你總是可以構建一個Map<Integer,Integer>並將映射到您所獲得的id的XML保存爲Customer在數據庫中創建它之後。然後,當您加載Order對象時,您可以在外部對象上設置新的校正ID。

希望這會有所幫助。讓我知道一些關於如何閱讀對象的更多細節,我可以舉一個更好的例子來說明如何構建對象圖。

+0

嗯,是的,我同意在保存任何內容之前創建內存中的所有對象並設置所有對象關係都是可行的,但是這對於最簡單或小型的數據集都是解決方案。它會打開一整個「蠕蟲的一竅不通:如果數據集是另一臺桌面或服務器數據庫的一部分 - 重寫ID肯定會破壞事情。或者,如果ID用於其他內容,比如創建賬單或交付通知以及某人需要從備份中恢復,該怎麼辦?更改數據庫還原的ID是每個自我尊重的數據庫管理員的一大訣竅... – 2011-03-07 18:22:04

+0

如果您正在討論數據庫還原,我會同意更改ids是baaad。我以爲你在談論的是一個「小」的Android應用程序,它正在從可能存在重疊ID的XML導入額外的記錄。如果在其他數據庫中引用了重疊的id,則會出現其他問題。我的答案的第二部分沒有幫助嗎?它向您展示瞭如何使用第二個對象將不生成的ID插入到同一個表中。 – Gray 2011-03-08 16:19:23

+0

另外,我在回答中非常明確地指出,將對象組裝在內存中僅適用於少量數據。你真的讀過整個答案嗎? – Gray 2011-03-08 16:30:51

相關問題