【问题标题】:DAO layer can return a JDBC ResultSet (Java)DAO 层可以返回一个 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)。

标签: java jakarta-ee jdbc dao


【解决方案1】:

不,业务层不应该处理ResultSets。该层的职责是处理业务逻辑,与数据的来源(在本例中为数据库)无关。

处理这个问题的一种方法是从数据源层返回Data Transfer Objects (DTO),然后在业务层处理它们。这样,数据可以来自多种来源(数据库、平面文件、Web 服务、其他集成),并且业务层不需要更改。

【讨论】:

    【解决方案2】:

    我认为这是一个坏主意,因为 JDBC 类(ResultSet 就是其中之一)旨在用于从数据库中检索数据。现在,当您调用 DAO 方法时,您很可能希望获得一个域模型对象或它们的一些集合(我说的是findXXX-like 方法)。

    常见的最佳实践是不要将数据源通信暴露给外层(很可能暴露给服务层)。原因:您可能曾经用键值存储、文本文件或其他东西替换数据库。如果您继续返回ResultSet,您将不得不更改很多签名。

    【讨论】:

      【解决方案3】:

      看第一件事

      如果您在DAO 层内拥有所有DB 相关逻辑,例如connection 对象、resultset 等。

      那么在DAO层内部处理显然更好,并在DAO层本身关闭所有这些打开的connectionresult set

      如果您将result set 返回到业务层,那么您无法在DAO 层本身中关闭resultset

      这意味着您正在将您的 DAO 逻辑委托回业务层,这是打算做的

      业务相关的东西。

      如果关闭result set时出现异常怎么办,因为你已经返回

      业务层,它在业务层产生问题。

      你需要在业务层处理所有DAOexceptions

      所以避免在业务层中使用resultset 或任何DB 相关的东西。

      并将其纯粹用于业务逻辑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-18
        • 2015-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        相关资源
        最近更新 更多