В теле метода isDataExist()
много повторяющегося кода, который сложно поддерживать и расширять (если вам нужно добавить еще 3 таблицы, размер кода удвоится). Кроме того, логика не является оптимальной, так как она будет проходить по всем таблицам, даже если результата первой достаточно для возврата true
.
Вот упрощенная версия (обратите внимание, что у меня нет 't проверил код, и могут быть ошибки, но этого должно быть достаточно, чтобы объяснить концепцию):
public boolean isDataExist(Employee emp) {
List<String> tableNames = List.of("Table1", "Table2", "Table3");
for (String tableName : tableNames) {
if (existsInTable(tableName, emp.getId())) {
return true;
}
}
return false;
}
private boolean existsInTable(String tableName, Long employeeId) {
String query = String.format("SELECT count(*) FROM %s WHERE emp_id=:id", tableName);
long count = (long)session
.createQuery(query)
.setParameter("id", employeeId)
.getSingleResult();
return count > 0;
}
isDataExist()
содержит список всех имен таблиц и выполняет итерации по ним до первого успешного обращения ктребуемый Employee id
, в этом случае возвращается true
. Если метод не найден ни в одной таблице, метод возвращает false
.
private boolean existsInTable(String tableName, Long employeeId)
- вспомогательный метод, который выполняет фактический поиск employeeId
в указанном tableName
. Я изменил запрос так, чтобы он просто возвращал счетчик (0 или более) вместо реальных объектов сущности, поскольку они не требуются, и нет смысла их извлекать.
РЕДАКТИРОВАТЬ в ответ на «Второй подход»
Соответствует ли Second Approach
требованиям? Если это так, то это «правильный подход» к проблеме. :)
Я бы реорганизовал метод deleteEmployeeDetails
, чтобы либо вернуть boolean
(если ожидается только два возможных результата), либо вернуть пользовательский Enum
, так как использование String
здесь некажется уместным.
В deleteEmployeeDetails
есть повторяющийся код, и это никогда не будет хорошей вещью. Вы должны отделить логику, которая решает тип response
от кода, который его строит, что облегчает отслеживание, отладку и расширение кода при необходимости.
Дайте мне знать, если вам нужен пример кодаиз приведенных выше идей.
РЕДАКТИРОВАТЬ # 2
Вот пример кода в соответствии с запросом.
Сначала мы определим Status
enum
, который следует использовать в качестве типа возврата из методов MasterDao
:
public enum Status {
DELETE_SUCCESS("Success", "200", "True", "Record deleted successfully"),
DELETE_FAIL("Fail", "200", "False", ""),
DEACTIVATE_SUCCESS("Success", "200", "True", "Record deactivated successfully"),
DEACTIVATE_FAIL("Fail", "200", "False", ""),
ERROR("Fail", "500", "False", "");
private String status;
private String statusCode;
private String result;
private String reason;
Status(String status, String statusCode, String result, String reason) {
this.status = status;
this.statusCode = statusCode;
this.result = result;
this.reason = reason;
}
// Getters
}
MasterDao
методы изменены для возврата Status
вместо String
или boolean
:
public Status deleteEmployeeDetails(Employee employee) {
return Status.DELETE_SUCCESS; // or Status.DELETE_FAIL
}
public Status deactivateEmployee(Employee employee) {
return Status.DEACTIVATE_SUCCESS; // or Status.DEACTIVATE_FAIL
}
Вот новый метод deleteEmployee()
:
public Response deleteEmployee(Employee employee) {
Status status;
String reason = null;
try {
status = masterDao.deleteEmployeeDetails(employee);
} catch (Exception e) {
if (isConstraintViolationException(e)) {
status = masterDao.deactivateEmployee(employee);
} else {
status = Status.ERROR;
reason = "# EXCEPTION : " + e.getMessage();
}
}
return buildResponse(status, reason);
}
Он использует два простых служебных метода (вы можете сделать их статическими или экспортировать в служебный класс, так как они не зависят от внутреннего состояния).
Первый проверяет, является ли основная причина выданного исключения ConstraintViolationException
:
private boolean isConstraintViolationException(Throwable throwable) {
Throwable root = throwable;
while (root != null && !(root instanceof ConstraintViolationException)) {
root = root.getCause();
}
return root != null;
}
А второй создает Response
из Status
и a reason
:
private Response buildResponse(Status status, String reason) {
Response response = new Response();
response.setStatus(status.getStatus());
response.setStatusCode(status.getStatusCode());
response.setResult(status.getResult());
if (reason != null) {
response.setReason(reason);
} else {
response.setReason(status.getReason());
}
return response;
}
Если вам не нравится загружать Status enum
сообщениями по умолчанию Response
, вы можете удалитьэто из дополнительной информации:
public enum Status {
DELETE_SUCCESS, DELETE_FAIL, DEACTIVATE_SUCCESS, DEACTIVATE_FAIL, ERROR;
}
И используйте операторы switch
или if-else
в buildResponse(Status status, String reason)
методе для построения ответа на основе типа Status
.