2016-03-04 74 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风格的操作,因为您应该将操作分离到适当的终点,而不是将它们合并为一个联合操作。