Как абстрагировать мою бизнес-логику и определения объектов от кода доступа к моей базе данных? - PullRequest
1 голос
/ 19 августа 2011

Итак, у меня есть база данных с 2 таблицами - Workflows и 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);
}

Каждый объект рабочего процесса имеет список для хранения шагов, относящихся к определенному рабочему процессу, а затем каждый шаг WorkflowStep имеет карту, которая используется для хранения данных, взятых из третьей таблицы.:

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();
}

Имея в виду этот код, я получаюследующая «процедура» для инициализации рабочего процесса со всеми его рабочими шагами и их параметрами:

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()));
     }

Я думаю, что у меня хороший уровень развязки, но мне интересно, можно ли это как-то реорганизовать - например, возможно, переместить шаг.setParameters для метода класса WorkflowStep, но тогда мне придется передать ссылку на соединение с базой данных (db) на объект WorkflowStep, но, на мой взгляд, это нарушит разделение?Так как бы вы, люди, реорганизовали этот код?

Ответы [ 2 ]

2 голосов
/ 20 августа 2011

Похоже, что вы катите свой собственный ORM .Мое предложение было бы использовать один из существующих, таких как Hibernate .

0 голосов
/ 20 августа 2011

Это функция Object Relational Mapper . Он служит для отвлечения вашего доступа к БД от вашей бизнес-модели. Фактически, при правильном использовании библиотека ORM позволяет вообще не писать код базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...