DAO 实现:使 DAO 对象成为其他 DAO 的属性

Posted

技术标签:

【中文标题】DAO 实现:使 DAO 对象成为其他 DAO 的属性【英文标题】:DAO implementation : Making a DAO object a property of other DAO 【发布时间】:2016-10-05 04:11:54 【问题描述】:

如何使 DAO 对象成为其他 DAO 的属性?

假设我有一个带有 Department 属性的 Employee 对象

public class Employee 
     public Department;

      //setter and getters
  

我有这个 EmployeeDAO 和 DepartmentDAO 接口以及相应的实现

我有 DAOFactory

public abstract class DAOFactory 

// db connection instantiation here

public IEmployeeDAO getEmployeeDAO() 
    return new EmployeeDAOImpl(this);


public IDepartmentDAO getDepartmentDAO() 
    return new DepartmentDAOImpl(this);

我有一个 servlet 实例化这个 DAOfactory

public class EmployeeController extends HttpServlet 

public EmployeeController() 
    super();
    DBUtils dbInstance = DBUtils.getInstance("mysql");
    System.out.println("DAOFactory successfully obtained: " + dbInstance);

    // Obtain UserDAO.
    employeeDAO = dbInstance.getEmployeeDAO();
    departmentDAO = dbInstance.getDepartmentDAO();
    jobDAO = dbInstance.getJobDAO();


protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException 

            employees = employeeDAO.findAll();

            request.setAttribute("employees", employees);


我的问题是,当我调用employeeDAO 的findAll 方法时,如何在employeeDAO 或其实现中映射Department 对象?

我在尝试绘制结果时遇到了类似的情况:

    private  Employee map(ResultSet rs) throws SQLException 
    Employee employee = new Employee();

    employee.setEmployeeID(rs.getInt("EMPLOYEE_ID"));
    employee.setFirstName(rs.getString("FIRST_NAME"));
    employee.setLastName(rs.getString("LAST_NAME"));

    Department department = new DepartmentDAOImpl().getDepartmentByID(rs
            .getInt("DEPARTMENT_ID"));

    employee.setDepartment(department);

    return employee;

但我认为这是一种错误的做法。有人可以帮我解决这个问题吗?

【问题讨论】:

为什么这是错误的方法?有什么不按预期工作吗? (虽然我会考虑使用 JPA 而不是手动对象映射,因为它为您完成了所有的 dao。虽然它找到了比扩展 HttpServlets 更高级别的抽象) 因为我直接创建了一个 DAO 实现的实例,它应该被 DAO 接口隐藏/或隐藏。我的目标是在调用employeeDAO.findAll(); 后使这成为可能。我也看过一些关于 JPA 的文章。我计划在我未来的项目中实施它。 【参考方案1】:

EmployeeDAOImpl 依赖于 IDepartmentDAO。与其直接实例化一个,不如将其声明为依赖项,并让构造 EmployeeDAOImpl 的代码弄清楚如何解决它。

假设

interface IEmployeeDAO 
    Employee load(long id);

interface IDepartmentDAO  
    Department load(long id);

因为接口需要构造函数中需要的 dao

class EmployeeDAOImpl implements IEmployeeDAO 

    private final DAOFactory factory;
    private final IDepartmentDAO departmentDAO;

    public EmployeeDAOImpl(DAOFactory factory, IDepartmentDAO departmentDAO) 
        this.factory = factory;
        this.departmentDAO = departmentDAO;
    
    ...

现在您可以在任何地方使用它。例如

@Override
public Employee load(long id) 
    ...
    long departmentId = ....
    Department department = departmentDAO.load(departmentId);
    employee.department = department;
    return employee;

您的DAOFactory 知道您无论如何都使用哪种实现,现在可以通过添加一个简单的参数来提供依赖项

public IEmployeeDAO getEmployeeDAO() 
    return new EmployeeDAOImpl(this, getDepartmentDAO());

【讨论】:

非常感谢您帮助我,先生。 哦,另一个问题,如果我有一个将员工类扩展为属性的经理对象,我该如何实例化 Department DAO? @GmChill 也许同样的方式(使其成为构造函数的参数)。但我也不确定你是什么意思。经理通常不应该 extend 它管理的事物,它只需要对该事物的引用:"What is the Liskov Substitution Principle?" 我仍然很困惑,但我认为我做错了。非常感谢 zapl 先生的帮助。

以上是关于DAO 实现:使 DAO 对象成为其他 DAO 的属性的主要内容,如果未能解决你的问题,请参考以下文章

通用 DAO 如何为所有不同的 DAO 实现返回相同的类型?

为什么在Dao设计模式或其他设计模式中使用接口

Spring 对 DAO 的支持

DAO

PHP DAO 让用户彼此成为朋友(技术上)

JavaWeb技术:DAO设计模式