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

Java 如何从数据库访问代码中抽象出业务逻辑和对象定义?,java,design-patterns,orm,Java,Design Patterns,Orm,因此,我有一个包含两个表的数据库—工作流和工作流步骤—我希望使用存储在那里的行在java中创建对象,但关键是我希望将数据库代码与应用程序代码分离。从一开始-当创建工作流/工作流步骤对象时,应用程序的其余部分将不必担心数据库访问。这就是我所拥有的: public Workflow getPendingWorkflowId() { int workflowid = -1; Statement statement = null; ResultSet rs = null;

因此,我有一个包含两个表的数据库—工作流和工作流步骤—我希望使用存储在那里的行在java中创建对象,但关键是我希望将数据库代码与应用程序代码分离。从一开始-当创建工作流/工作流步骤对象时,应用程序的其余部分将不必担心数据库访问。这就是我所拥有的:

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);
}
每个工作流对象都有一个列表来存储与特定工作流相关的步骤,然后每个工作流步骤都有一个映射,用于存储从第三个表中获取的数据:

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;
} 
公共列表GetUnworkedSepsByWFID(int id){
//可以改变
ArrayList步骤=新建ArrayList();
Statement=null;
结果集rs=null;
试一试{
statement=con.createStatement();
rs=语句.executeQuery(“从“工作流”步骤中选择*,其中“工作流”id`=“+id+”,状态=“尚未启动”);
while(rs.next()){
添加(新的工作流步骤(rs.getInt(1)、rs.getInt(3)、rs.getInt(4));
}
语句。close();
rs.close();
}catch(SQLException-ex){
Logger.getLogger(DBAccessor.class.getName()).log(Level.SEVERE,null,ex);
System.out.println(“获取工作流id时出错”);
}
返回步骤;
} 
下面是对第三个表的查询: 公共映射getParametersForStep(int workflowId,int workstepPos){

Statement=null;
结果集rs=null;
Map hMap=newhashmap();
试一试{
statement=con.createStatement();
//可能是错的
rs=语句。执行程序(“选择wf.id作为workflowID,ws_steps.id作为workflowStepsID,name,param_value,pathname作为工作流中的wf内部连接工作流_steps作为wf.id=ws_steps.workflow_id内部连接ws_参数作为ws_参数。ws_id=ws_steps.id内部连接子模块_参数作为子模块上的wf_参数。id=ws_参数。sp_id和wf.id=“+workflowID+”和ws_steps.workflow_position=“+workstepPos”);
字符串paramName=null;
字符串参数值=null;
while(rs.next()){
paramName=rs.getString(“名称”);
if(rs.getString(“参数值”)==null){
paramValue=rs.getString(“路径名”);
}否则{
paramValue=rs.getString(“param_值”);
}
hMap.put(paramName,paramValue);
}
语句。close();
rs.close();
返回hMap;
}catch(SQLException-ex){
Logger.getLogger(DBAccessor.class.getName()).log(Level.SEVERE,null,ex);
System.out.println(“获取工作流步骤参数名称时出错”);
}
return Collections.emptyMap();
}
考虑到这段代码,我最终使用以下“过程”初始化工作流及其所有工作流步骤及其参数:

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()));
     }
Workflow wf=db.getPendingWorkflowId();
initSteps(db.getUnworkedStepsByWFId(wf.getId());
迭代器it=wf.getSteps();
while(it.hasNext()){
WorkflowStep=it.next();
setParameters(db.getParametersForStep(wf.getId(),step.getPosInWorkflow());
}

我认为我有一个很好的解耦级别,但我想知道这是否可以以某种方式进行重构-例如,可能会将step.setParameters移动到WorkflowStep类的一个方法,但是我必须传递对数据库连接(db)的引用对于WorkflowStep对象,但在我看来,这将打破脱钩?那么人们将如何重构此代码呢?

这是一个的功能。它用于从您的业务模型中抽象出您的DB访问权限。事实上,如果使用得当,ORM库允许您根本不编写数据库代码。

看起来您正在滚动数据库own。我的建议是使用现有的一个,如。

我使用MyBatis,但Hibernate def似乎是流行的选择。这真的不值得使用-1。它最初的标题可能措词不当,但事实是,如果您还不熟悉ORM,那么您应该能够提出这样的问题并收到答复答案是“使用ORM”
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()));
     }