我的Java项目有一个使用Java API JDBC的DAO层; JDBC返回ResultSet以从数据库中获取信息。
考虑到带有图层的编程范例,将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;
}
答案 0 :(得分:2)
不,业务层不应该处理ResultSets
。该层的职责是处理业务逻辑,与数据来源无关(在本例中为数据库)。
处理此问题的一种方法是从数据源层返回Data Transfer Objects
(DTO),然后在业务层中处理它们。这样,数据可以来自众多来源(数据库,平面文件,Web服务,其他集成),业务层也不需要更改。
答案 1 :(得分:1)
我认为这是一个坏主意,因为JDBC类(ResultSet
就是其中之一)被设计用于从数据库中检索数据。现在,当您调用DAO方法时,您很可能期望获得域模型对象或其中的一些集合(我正在谈论findXXX
- 类似方法)。
常见的最佳做法是不将数据源通信暴露给外层(最有可能是服务层)。理由:您可以使用键值存储,文本文件或其他内容替换数据库。如果你继续回归ResultSet
,你将不得不改变很多签名。
答案 2 :(得分:0)
先看看
如果DB
图层中包含DAO
对象,connection
等内的所有resultset
相关逻辑。
然后处理DAO
图层并在connection
图层内部关闭所有这些已打开的result set
和DAO
显然会更好。
如果您将result set
返回给“商务”图层,则无法在resultset
图层中关闭DAO
。
这意味着您将DAO
逻辑移植回了旨在执行的业务层
与业务相关的东西。
如果在关闭result set
时发生一些异常会怎样,因为您已经返回
业务层,它会在业务层中创建问题。
您需要处理业务层内的所有DAO
exceptions
。
因此请避免在业务层内使用resultset
或任何DB
相关内容。
并将其纯粹用于商业逻辑。