2016-03-04 64 views
0

我很困惑實現了用於DAODatabase(用於Oracle 11 xe)的CRUD方法。 問題是,在通常存儲到Map集合的情況下,方法(更新)會在Map集合中插入新元素或將其更新(鍵值數據,如ID:AbstractBusinessObject)。當你寫下類似myHashMap.add(element)的東西時,你並不關心它。這種方法(更新)廣泛用於項目的業務邏輯。DAO:InMemory實現和數據庫實現之間的區別

顯然,在使用Oracle的情況下,我必須關心插入和更新現有的元素。但我被困在選擇如何實現它的方式:

Oracle中沒有所謂的UPSERT的固有功能(至少在xe11g r2版本中)。不過,我可以像這樣通過SQL查詢模擬必要的功能:

INSERT INTO mytable (id1, t1) 
    SELECT 11, 'x1' FROM DUAL 
    WHERE NOT EXISTS (SELECT id1 FROM mytble WHERE id1 = 11); 

UPDATE mytable SET t1 = 'x1' WHERE id1 = 11; 
(src:http://stackoverflow.com/a/21310345/2938167) 

通過使用這種類型的查詢(第一 - 插入,第二個 - 更新),我相信這些數據大多將被插入不更新(在至少它會是非常罕見的)。(可能不是最佳的併發性?)。

好的,這是可能的。但在這一點上,我困惑,以決定:

- 我應該寫一個SQL函數(當然,approriate參數),這和通過Java

稱之爲 - 或者我應該簡單地處理系列查詢preparedStatements,並通過.executeUpdate/.executeQuery進行查詢?我是否應該處理整個UPSERT SQL代碼中的一個preparedStatment或將其拆分爲一個方法體內的幾個SQL查詢和準備語句? (我正在使用Tomcat的連接池,並通過靜態方法getConnection()將連接實例傳遞給DAODatabase中的每個方法實現)?

有沒有解決UPSERT任務的另一種可能性?

回答

1

相當於你UPSERT聲明似乎是使用MERGE

MERGE INTO mytable d 
USING (SELECT 11 AS id, 'x1' AS t1 FROM DUAL) s 
     ON (d.id = s.id) 
WHEN NOT MATCHED THEN 
    INSERT (d.id, d.t1) VALUES (s.id, s.t1) 
WHEN MATCHED THEN 
    UPDATE SET d.t1 = s.t1; 

您也可以使用(或在程序包):

DECLARE 
    p_id MYTABLE.ID%TYPE := 11; 
    p_t1 MYTABLE.T1%TYPE := 'x1'; 
BEGIN 
    UPDATE mytable 
    SET t1 = p_t1 
    WHERE id = p_id; 

    IF SQL%ROWCOUNT = 0 THEN 
    INSERT INTO mytable (id, t1) VALUES (p_id, p_t1); 
    END IF; 
END; 
/

然而,當你正在處理一個CRUD請求 - 如果您正在執行創建操作,那麼它應該由INSERT表示(如果已經存在,那麼您應該拋出HTTP狀態代碼400 Bad Request409 Conflict ,如果您正在執行更新操作,它應該由UPDATE表示(如果沒有更新,則返回等效錯誤404 Not Found

因此,儘管MERGE符合您的描述,但我認爲它不代表REST風格的操作,因爲您應該將操作分離到適當的終點,而不是將它們合併爲一個聯合操作。

相關問題