Итак, у меня есть база данных с 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, но, на мой взгляд, это нарушит разделение?Так как бы вы, люди, реорганизовали этот код?