DAO:内存实现和数据库实现之间的区别

DAO: diffrence between InMemory implementation and Database Implementation

我对 DAODatabase(对于 Oracle 11 xe)的 CRUD 方法的实现感到困惑。 问题是 "U"-方法(更新)在通常存储到 Map 集合的情况下会插入一个新元素或更新它(键值数据如 ID:AbstractBusinessObject) 在地图集合中。当你写 myHashMap.add(element) 这样的东西时,你不关心它。该方法(更新)在项目的业务逻辑中被广泛使用。

显然,在使用 Oracle 的情况下,我必须关心现有元素的插入和更新。但我坚持选择如何实现它的方式:

Oracle 中没有所谓的UPSERT 的内在函数(至少在xe11g r2 版本中)。但是,我可以通过 SQL-query 像这样模拟必要的功能:

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:

通过使用这种查询(第一次-插入,第二次-更新)我推测数据主要是插入而不是更新(至少它会相当罕见)。(可能不是并发的最佳选择?)。

好的,这是可能的。但在这一点上我很难决定:

-- 我是否应该为此编写一个 SQL 函数(当然带有适当的参数)并通过 Java

调用它

-- 或者我应该简单地处理对 preparedStatements 的一系列查询并通过 .executeUpdate/.executeQuery 来完成它们?我应该为一个 preparedStatment 处理整个 UPSERT SQL 代码,还是将其拆分为多个 SQL 查询和一个方法体内的准备语句? (我正在使用 Tomcat 的连接池,并通过静态方法 getConnection() 将连接实例传递给 DAODatabase 中的每个方法实现)?

还有其他解决UPSERT任务的可能性吗?

相当于您的 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 表示(如果没有要更新的内容,则 return 404 Not Found.

的等效错误

因此,虽然 MERGE 符合您的描述,但我认为它不能代表 RESTful 操作,因为您应该将操作分离到适当的终点而不是合并成为联合行动。