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 Request
或 409 Conflict
,视情况而定),如果您正在执行更新操作,则它应由 UPDATE
表示(如果没有要更新的内容,则 return 404 Not Found
.
的等效错误
因此,虽然 MERGE
符合您的描述,但我认为它不能代表 RESTful 操作,因为您应该将操作分离到适当的终点而不是合并成为联合行动。
我对 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 Request
或 409 Conflict
,视情况而定),如果您正在执行更新操作,则它应由 UPDATE
表示(如果没有要更新的内容,则 return 404 Not Found
.
因此,虽然 MERGE
符合您的描述,但我认为它不能代表 RESTful 操作,因为您应该将操作分离到适当的终点而不是合并成为联合行动。