如何从我的数据库访问代码中抽象出业务逻辑和对象定义?

时间:2011-08-19 19:58:11

标签: java design-patterns orm

所以我有一个包含2个表的数据库 - 工作流和WorkflowSteps我想使用存储在那里的行来创建java中的对象但是我想要将我的数据库代码与我的应用程序代码分开。从一点开始 - 当创建Workflow / WorkflowSteps对象时,应用程序的其余部分将不必担心数据库访问。所以这就是我所拥有的:

public Workflow getPendingWorkflowId() {
    int workflowid = -1;
    Statement statement = null;
    ResultSet rs = null;
    try {
        statement = con.createStatement();

        rs = statement.executeQuery("SELECT id FROM xxx.workflows WHERE status = 'NOT-YET-STARTED' LIMIT 1");

        while (rs.next()) {
            workflowid = rs.getInt("id");
        }

        statement.close();
        rs.close();

    } catch (SQLException ex) {
        Logger.getLogger(DBAccessor.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Error fetching workflows id");
    }

    return new Workflow(workflowid);
}

每个工作流对象都有一个List,用于存储与特定工作流有关的步骤,然后每个WorkflowStep都有一个Map,用于存储从第3个表中获取的数据:

public List<WorkflowStep> getUnworkedStepsByWFId(int id) {

    //can be changed
    ArrayList<WorkflowStep> steps = new ArrayList<WorkflowStep>();
    Statement statement = null;
    ResultSet rs = null;
    try {
        statement = con.createStatement();

        rs = statement.executeQuery("SELECT * FROM `workflow_steps` WHERE `workflow_id` =" + id + " AND status =  'NOT-YET-STARTED'");

        while (rs.next()) {

            steps.add(new WorkflowStep(rs.getInt(1), rs.getInt(3), rs.getInt(4)));

        }

        statement.close();
        rs.close();

    } catch (SQLException ex) {
        Logger.getLogger(DBAccessor.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Error fetching workflows id");
    }

    return steps;
} 

这是第3个表的查询:     public Map getParametersForStep(int workflowId,int workstepPos){

    Statement statement = null;
    ResultSet rs = null;
    Map<String, String> hMap = new HashMap<String, String>();

    try {
        statement = con.createStatement();

        //MIGHT BE WRONG
        rs = statement.executeQuery("SELECT wf.id AS workflowID, ws_steps.id AS workflowStepsID, name, param_value, pathname FROM workflows AS wf INNER JOIN workflow_steps AS ws_steps ON wf.id = ws_steps.workflow_id INNER JOIN ws_parameters ON ws_parameters.ws_id = ws_steps.id INNER JOIN submodule_params ON submodule_params.id = ws_parameters.sp_id AND wf.id =" + workflowId + " AND ws_steps.workflow_position =" + workstepPos);
        String paramName = null;
        String paramValue = null;

        while (rs.next()) {

            paramName = rs.getString("name");

            if (rs.getString("param_value") == null) {
                paramValue = rs.getString("pathname");
            } else {
                paramValue = rs.getString("param_value");
            }

            hMap.put(paramName, paramValue);
        }

        statement.close();
        rs.close();
        return hMap;

    } catch (SQLException ex) {
        Logger.getLogger(DBAccessor.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Error fetching workflow step parameters names");
    }

    return Collections.emptyMap();
}

记住这些代码后,我最终使用以下“过程”来初始化工作流及其所有WorkflowSteps及其参数:

Workflow wf = db.getPendingWorkflowId();
wf.initSteps(db.getUnworkedStepsByWFId(wf.getId()));
Iterator<WorkflowStep> it = wf.getSteps();

     while(it.hasNext()) {
         WorkflowStep step = it.next();             
         step.setParameters(db.getParametersForStep(wf.getId(), step.getPosInWorkflow()));
     }

我认为我有很好的解耦程度,但我想知道这是否可以以某种方式重构 - 例如,可能将step.setParameters移动到WorkflowStep类的方法但是我必须传递对数据库连接的引用(db)到WorkflowStep对象,但在我的视图中,这将破坏解耦?那么你们如何重构这段代码呢?

2 个答案:

答案 0 :(得分:2)

您似乎正在推动自己的ORM。我的建议是使用现有的Hibernate之一。

答案 1 :(得分:0)

这是Object Relational Mapper的功能。它用于从您的业务模型中抽象出您的数据库访问。实际上,使用得当,ORM库允许您根本不编写数据库代码。