【问题标题】:DAO pattern in 3 level Architecture. How to deal with complex queries3 级架构中的 DAO 模式。如何处理复杂的查询
【发布时间】:2014-05-18 12:00:17
【问题描述】:

我目前正在使用 3 层 ui-service-dao 开发应用程序。在 dao 级别,我使用的是 Spring 的 jdbcTemplate 。到目前为止一切顺利,但我遇到了一个我想了解更多的情况

我的 DAO 一开始只有简单的 CRUD 方法。在服务级别,我正在检查输入值并委托给 DAO 并处理事务。

现在我需要更多类似下面的东西

列出 getAllBooksByAuthorName(字符串名称)

我的问题是把这个放在哪里?在DAO层使用sql或在服务中使用CRUD的核心方法和简单的java计算

我宁愿尽可能多地使用sql,而不是在服务层进行计算。但是现在好像每一个新的方法,我也需要改变DAO的接口,在服务的接口中制作对应的方法。然后服务就变成了委托者和参数检查器。感觉不对。

【问题讨论】:

    标签: java spring dao spring-jdbc


    【解决方案1】:

    您的意见非常有效,但我不明白您为什么会怀疑。DAO 模式通常会减少业务逻辑和持久性逻辑之间的耦合。

    public interface BooksDAO{
       public boolean save(Book book);
       public boolean update(Book book);
       public boolean findByBookIsbn(int isbn);
       public boolean delete(Book book);
       //here is what you want
       public List<Book> getAllBooksByAuthorName(String name);
    }
    

    现在您可以为 BooksDao 提供不同的实现,例如 HibernateBooksDaoImpl 或 JdbcBooksDAOImpl。 DAO 模式使编写隔离的junit 测试变得容易并且执行速度更快。

    如果您有复杂的查询,您仍然可以使用 dao 模式。基本上有办法在实现端编写复杂的查询,无论是简单的jdbc(可以使用sql)还是spring jdbc模板(仍然可以使用sql)或hibernate使用标准。 看: http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/Criteria.html

    更多信息请看:

    http://javarevisited.blogspot.com/2013/01/data-access-object-dao-design-pattern-java-tutorial-example.html
    http://www.oracle.com/technetwork/articles/entarch/spring-jdbc-dao-101284.html

    【讨论】:

      【解决方案2】:

      然而它应该是这样的。在业务逻辑被简化为除了调用一个 DAO 方法之外,那么你很幸运拥有简单的业务逻辑。

      让服务调用 BookDAO.findAll() 并过滤由 DAO 返回的庞大书籍列表显然是非常低效且完全不现实的。 SQL 是适合这项工作的工具。

      请注意,只能通过接口进行模拟的时代已经过去。不再需要使用接口来定义 DAO 方法了。

      【讨论】:

        【解决方案3】:

        例如,您可以使用实体控制边界模式。

        您的包结构将如下所示:

        在您的应用程序的命名空间下,您可以引入一个名为“business”的包,在该包中可以有由业务职责命名的包,这些包分为“实体”、“控制”和“边界”。

        com.example.myapplication.business.project.entity -> 如果您使用 JPA,您的所有实体都可以存储在此包中,包含 DTO

        com.example.myapplication.business.project.control -> 在这个包中可以存储重构的服务,例如,如果不止一个边界需要DAO-Code,代码可以在这个包中重构

        com.example.myapplication.business.project.boundary -> 这个包包含客户端可以看到的所有服务(例如你的网页)

        在“presentation”包中可以存储你的 ui 控制器,并且 ui 控制器应该只访问存储在边界包中的服务。

        com.example.myapplication.presentation.project

        通过使用这种模式,您可以避免使用委托,因为存储在边界包中的服务也可以包含特定于 sql 的内容,并且所有服务和实体都在它们所属的包中。

        该模式也可以在 JEE 之外使用。 Adam Bien 在 JEE 架构中彻底改变了这种模式,我也在自己的项目中使用它。这是一个例子 -> http://www.youtube.com/watch?v=JWcoiXNoKxk#t=2380

        您的边界方法可能如下所示:

        public interface ProjectService {
        public Project createProject(Project project);
        public Project getProjectById(String projectId);
        public List<Project> getProjectList(ListConfig config); // where ListConfig is a class containing information of how the list should be sorted, optional pagination information, etc, so that the interface must not be changed every time you need a new parameter
        public Project updateProject(Project project);
        public void deleteProject(String projectId);
        public Project addFeature(Project project, Feature feature);
        

        }

        @ayan ahmedov:对不起,我第一次尝试回答你的问题时,很遗憾我编辑了你的问题,我的答案在你问题的内容区域。我已经“还原”了意外更改。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-19
          • 2012-11-06
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          • 2018-02-02
          相关资源
          最近更新 更多