Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns DAO设计模式与连接处理_Design Patterns_Dao - Fatal编程技术网

Design patterns DAO设计模式与连接处理

Design patterns DAO设计模式与连接处理,design-patterns,dao,Design Patterns,Dao,我有EmployeeDAOImpl.java和DepartmentDAOImpl.java。现在我从数据服务层调用这两个。EmployeeDAO和DepartmentDAO是接口,它们只有abtract CRUD方法。在服务层中,我有两个方法调用createEmployee(Employee Employee)和createDepartment(Department Department),方法中带有。这两个呼叫应该在同一事务中,这意味着只有在两个呼叫成功后才能关闭连接。现在你们知道如何提供连接

我有EmployeeDAOImpl.java和DepartmentDAOImpl.java。现在我从数据服务层调用这两个。EmployeeDAO和DepartmentDAO是接口,它们只有abtract CRUD方法。在服务层中,我有两个方法调用createEmployee(Employee Employee)和createDepartment(Department Department),方法中带有。这两个呼叫应该在同一事务中,这意味着只有在两个呼叫成功后才能关闭连接。现在你们知道如何提供连接了吗。我不想在DepartmentDAOImpl和EmployeeDAOImpl的构造函数中提供连接。我也不想使用SpringAOP或ThreadLocale,有什么解决方案吗

您没有解释为什么不想提供到DAO构造函数的连接或使用Spring AOP或ThreadLocale

我想说,连接获取是事务管理的一部分,事务管理是服务层的责任。它应该为DAO提供连接到数据库所需的内容

你说过你不会怎么做,但没有提出你会怎么做的想法

我认为服务应该从池中获取连接,将其提供给DAO,管理事务,并在用例完成时将连接返回到池中

我将把实现细节留给您,因为您不想使用Spring。使用直接的JDBC是可能的。你只需要更加努力地工作就可以了

如果您坚持不使用Spring或AOP,您的服务代码将如下所示:

package service;

public class FooServiceImpl implements FooService {
    public void saveFoo(Foo f) {
        Connection connection = null;
        Statement st = null;
        try {
            connection = ConnectionPool.checkout();
            connection.setAutoCommit(false);
            // do something here
            connection.commit();
        } catch (Exception e) {
            rollback(connection);
            e.printStackTrace();
        } finally {
            close(st);
            close(connection);
        }
    }
}
Spring和AOP将在这里发挥作用。它将消除样板代码。这是你的选择

我不想使用Spring AOP或ThreadLocale

不幸的是(?)这就是Spring处理事务和连接的方式-(简而言之)一旦您从非事务上下文中输入
@Transactional
方法,它就会将负责该事务的数据库连接放在
ThreadLocal
中。这样,该事务中的每个方法都使用相同的连接,因此使用相同的事务。这完全是跨协议的,您只需使用
DataSource
抽象或
JdbcTemplate
(这优雅地隐藏了这种复杂性)

请注意,在多线程环境中,将连接作为构造函数参数传递是完全中断的。您应该通过
数据源
。Spring(或者EJB)将处理底层内容


稍微好一点的方法是将
连接
传递给每个DAO的每个方法。但这是sooo 90年代。。。你能详细说明一下你不喜欢Spring方法的哪些方面吗?

我正在做一个项目,人们不喝Spring kool-aid……我发现下面的模式对我很有效

Service-->*Manager-->DAOs
假设您有3个不同的表,它们必须在一个事务中更新(全部或无)。其中一个表是“父”表,其中的子表必须在父级保存期间更新

public class ParentServive
    private ParentManager parentManager; 

    public void save(Parent parent){
         parentManager.save(parent)
    }
}
创建一个所有*Manager类都将扩展的DAOManager

public class DAOManager{
...
..
  public Connection getConnection()throws DAOException{
  try{
    dataSource.getConnection();
    }catch(SQLException e){
    throw new DAOExceptoin(e);
    }
  }

    public Connection getTXConnection()throws DAOException{
     Connection connection  = dataSource.connection;
     connection.setAutoCommit(false);
     return connection;
  }

  public void close(Connection connectoin) throws DAOException{

  try{
      if ( !connection.getAutoCommit() ){
         connection.setAutoCommit(true);
     }
     connection.close();
     }catch(SQLException e){
      throw new DAOExceptoin(e);
    }
  }
}
现在您有了两个DAO,父表必须更新它们才能使保存有效—首先创建一个抽象DAOManager 请注意,我只打开了一个连接,可以回滚或提交所有表

 public class ParentManager extends DAOManager{
   private ParentDAO parentDAO;
   private ChildOneDAO childOneDAO;
   private ChildTwoDAO childTwoDAO;

   public save(Parent parent) throw DAOException{
      Connection connection = null;

      try{
      connection = getTXConnection(); 
      ParentDAO parentDAO   = new ParentDAO(connection);
      ChildTwoDAO childTwoDAO = new ChildOneDAO(connection);
      ChildTwoDAO childTwoDAO = new ChildTwoDAO(connection);

      parentDAO.save(...)

      childOneDAO.save(...)

      childTwoDAO.save(..)    


      connection.commit();

      }catch(Exception e){    
        connection.rollback();
      }finally{
      close(connection);
      }
   }
}

那么您的服务只能使用Manager类,而不用担心连接管理。。。每个“表”都有一个管理器,使用DAO是缺点。

+1-一个写得好、考虑周到的答案。我支持重新考虑Spring的建议。