2013-01-08 77 views
3

我正在使用SQLite數據庫來存儲可用於重建我正在開發的應用程序中使用的某些對象的數據。我正在存儲CheckIns,Recipients和ContactMethods。在Android中使用一對多和多對多關係的INSERT和SELECT語句

public class CheckIn { 
    private int id; 
    private boolean isEnabled; 
    private Date startTime; 
    private Repetition repetition; 
    private Set<Recipient> recipients; 
} 

public class Recipient {  
    private String name; 
    private Set<ContactMethod> contactMethods;  
} 

public class ContactMethod {  
    private String type; 
    private String address;  
} 

數據庫架構我已經想出了這些對象的定義:

CheckIn <--many -- to -- many--> Recipient 
Recipient <--one -- to -- many--> ContactMethod 

在Java中,如下這些對象的字段的定義:

這些對象的關係如下如下:

CREATE TABLE checkIn(
    _id    INTEGER PRIMARY KEY AUTOINCREMENT, 
    isEnabled   INTEGER, 
    startTime   INTEGER, 
    repetitionNum  INTEGER, 
    repetitionUnits TEXT 
); 

CREATE TABLE recipient(
    _id    INTEGER PRIMARY KEY AUTOINCREMENT, 
    name    TEXT 
); 

CREATE TABLE contactMethod(
    _id      INTEGER PRIMARY KEY AUTOINCREMENT, 
    type      TEXT, 
    address     TEXT, 
    recipientID    INTEGER, 
    FOREIGN KEY(recipientID) REFERENCES recipient(_id) ON DELETE CASCADE 
); 

CREATE TABLE checkIn_recipient(
    checkInID   INTEGER, 
    recipientID  INTEGER, 
    FOREIGN KEY(checkInID) REFERENCES checkIn(_id), 
    FOREIGN KEY(recipientID) REFERENCES recipient(_id) 
); 

我有兩個問題。

1.如何有效地將CheckIn插入數據庫及其相關對象?

更具體地說,如果我有一個Java中的CheckIn對象,尚未提交給數據庫,我該如何構造一個INSERT語句,它將CheckIn插入到CheckIn表中,並且還存儲新的CheckIn關係到一個或多個收件人?它似乎將關係存儲到收件人,我需要已經知道尚未設置的checkIn._id,因爲CheckIn尚未輸入到數據庫中。

2.在Android中,重建CheckIn對象的最佳方法是什麼,例如從數據庫查詢中重建?

我想我知道SQL查詢,我將需要得到正確的數據:

SELECT checkIn.*, recipient.name, contactMethod.type, contactMethod.address 
FROM checkIn 
JOIN checkIn_recipient 
    ON (checkIn._id = checkIn_recipient.checkInID) 
JOIN recipient 
    ON (checkIn_recipient.recipientID = recipient._id) 
JOIN contactMethod 
    ON (recipient._id = contactMethod.recipientID) 

此查詢會讓我包含所有的信息數據的行,我需要建立每一個對象數據庫中的CheckIn和Recipient,我知道如何獲得一個將遍歷這些行的Cursor對象。但是,由於單個CheckIn所需的數據出現在多行上,所以我對構造單個CheckIn對象的最佳方式感到困惑。如果我試圖編寫一個像public Set<CheckIn> getAllCheckIns()這樣的方法,它將返回存儲在數據庫中的所有CheckIns的集合,那麼是否需要運行上面的查詢,然後使用相同的checkIn._id循環每行,並在該循環內,每一行都有相同的recipient._id,等等?有沒有更好的方法來做到這一點?

對於長期的問題,我很抱歉。自今天上午以來,我只使用超過單表數據庫的SQL,而且我不想忽略任何重要信息。讓我知道如果我錯過了什麼。

回答

3

對問題1的回答:有2種可能的方式。

a。您可以找到插入的行的ID並使用它插入到第二個表中。如果您使用的Android插入方法如下所示,您可以找到插入的行的ID: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#insert%28java.lang.String,%20java.lang.String,%20android.content.ContentValues%29

此處您必須確保所有數據庫表都已提交或沒有提交。

b。你可以創建觸發器。觸發器是在指定的數據庫事件發生時自動執行的數據庫操作。 瞭解如何創建觸發器:http://www.sqlite.org/lang_createtrigger.html

因此,例如,您可以創建一個AFTER INSERT觸發器,當在檢入表中插入一行時將觸發該觸發器。然後在該觸發器中,您可以將行插入另一個表中。 當觸發器被觸發時,您可以訪問新插入的行。從表1中

  • 選擇 - 檢查表
  • 遍歷光標並準備入住對象:

    回答問題2: 我通常會做以下。

  • 在循環中,從表2中選擇 - 收件人表
  • 迭代收件人表並準備檢入對象。

這將涉及太多的數據庫選擇。

或者,您可以選擇所有數據一次,然後迭代準備對象。

我想說明的一點是,你必須遍歷:d

+0

我覺得這個答案,我發現這非常有幫助。非常感謝! – Genre