DAO 层可以返回一个 JDBC ResultSet (Java)
Posted
技术标签:
【中文标题】DAO 层可以返回一个 JDBC ResultSet (Java)【英文标题】:DAO layer can return a JDBC ResultSet (Java) 【发布时间】:2014-07-04 08:39:21 【问题描述】:我的 Java 项目有一个使用 Java API JDBC 的 DAO 层; JDBC 返回 ResultSets 以从数据库中获取信息。
考虑到分层的编程范式,将ResultSet对象返回业务层并将信息提取到其中是否正确?
根据层定义,业务层有责任将信息包装在领域对象(bean 等)中。但另一方面,它还没有看到 DAO 组件。
我附上这段代码来展示我的范例:
public static Hashtable<String, TreeSet<String>> getCodesByEditorial(Vector<Integer> familiesVector) throws Exception
DriverManager.registerDriver((Driver) Class.forName("ianywhere.ml.jdbcodbc.IDriver").newInstance());
Connection con = DriverManager.getConnection("jdbc:odbc:DSN=DBLIB");
String sqlQuery =
"SELECT re.codigo, li.editorial FROM li_li li " +
"LEFT OUTER JOIN tl_recambio re ON li.codigo = re.codigo " +
"WHERE li.editorial IS NOT NULL AND re.familia IN (" + buildFamilies(familiesVector) + ")" ;
PreparedStatement ps = con.prepareStatement(sqlQuery);
ResultSet res = ps.executeQuery();
//THIS CODE SHOULD BE INTO DAO LAYER????
Hashtable<String, TreeSet<String>> codesHashTree = new Hashtable<String, TreeSet<String>>();
while (res.next())
String code = res.getString("CODIGO");
String editorial = res.getString("EDITORIAL");
if (editorial != null)
TreeSet<String> bookTreeSet = codesHashTree.get(editorial);
if (bookTreeSet == null)
bookTreeSet = new TreeSet<String>();
bookTreeSet.add(code);
codesHashTree.put(editorial, bookTreeSet);
con.close();
return codesHashTree;
【问题讨论】:
从技术上讲,您可能会使用CachedRowSet
实现(它扩展了 ResultSet
接口),但泄漏数据库抽象通常是糟糕设计的标志(尤其是当它们是需要的资源时)被关闭,就像ResultSet
)。
【参考方案1】:
不,业务层不应该处理ResultSets
。该层的职责是处理业务逻辑,与数据的来源(在本例中为数据库)无关。
处理这个问题的一种方法是从数据源层返回Data Transfer Objects
(DTO),然后在业务层处理它们。这样,数据可以来自多种来源(数据库、平面文件、Web 服务、其他集成),并且业务层不需要更改。
【讨论】:
【参考方案2】:我认为这是一个坏主意,因为 JDBC 类(ResultSet
就是其中之一)旨在用于从数据库中检索数据。现在,当您调用 DAO 方法时,您很可能希望获得一个域模型对象或它们的一些集合(我说的是findXXX
-like 方法)。
常见的最佳实践是不要将数据源通信暴露给外层(很可能暴露给服务层)。原因:您可能曾经用键值存储、文本文件或其他东西替换数据库。如果您继续返回ResultSet
,您将不得不更改很多签名。
【讨论】:
【参考方案3】:看第一件事
如果您在DAO
层内拥有所有DB
相关逻辑,例如connection
对象、resultset
等。
那么在DAO
层内部处理显然更好,并在DAO
层本身关闭所有这些打开的connection
和result set
。
如果您将result set
返回到业务层,那么您无法在DAO
层本身中关闭resultset
。
这意味着您正在将您的 DAO
逻辑委托回业务层,这是打算做的
业务相关的东西。
如果关闭result set
时出现异常怎么办,因为你已经返回
业务层,它在业务层产生问题。
你需要在业务层处理所有DAO
exceptions
。
所以避免在业务层中使用resultset
或任何DB
相关的东西。
并将其纯粹用于业务逻辑。
【讨论】:
以上是关于DAO 层可以返回一个 JDBC ResultSet (Java)的主要内容,如果未能解决你的问题,请参考以下文章