gpt4 book ai didi

java - 如果存在引用则更新行,否则使用 spring boot 删除

转载 作者:行者123 更新时间:2023-12-02 09:23:19 25 4
gpt4 key购买 nike

需要指导 -

如何在没有可用引用时进行硬删除,以及在有引用时进行软删除,此操作应在单个方法本身中执行。

例如我有 1 个主表和 3 个事务表,主引用在所有 3 个事务表中均可用。现在,在删除主行时 - 我必须执行以下操作:如果主引用可用,则更新主表行,如果没有主引用。可以删除该行。

到目前为止我已经尝试过关注。

服务实现 -

public response doHardOrSoftDelete(Employee emp) {
boolean flag = iMasterDao.isDataExist(emp);
if(flag) {
boolean result = iMasterDao.doSoftDelete(emp);
} else {
boolean result = iMasterDao.doHardDelete(emp);
}
}

第二种方法:

众所周知,在删除记录时,如果引用可用,则会抛出 ConstraintViolationException,因此我们可以简单地捕获它并检查捕获的异常是否属于 ConstraintViolationException 类型,如果是,则调用 doSoftDelete () 方法并返回响应。所以在这里你不需要编写方法或任何东西来检查引用。但我不确定这是否是正确的方法。帮我解决一下就可以了。

这是我再次尝试的 -

public Response deleteEmployee(Employee emp) {
Response response = null;
try{
String status= iMasterDao.deleteEmployeeDetails(emp);
if(status.equals("SUCCESS")) {
response = new Response();
response.setStatus("Success");
response.setStatusCode("200");
response.setResult("True");
response.setReason("Record deleted successfully");
return response;
}else {
response = new Response();
response.setStatus("Fail");
response.setStatusCode("200");
response.setResult("False");
}
}catch(Exception e){
response = new Response();
Throwable t =e.getCause();
while ((t != null) && !(t instanceof ConstraintViolationException)) {
t = t.getCause();
}
if(t instanceof ConstraintViolationException){
boolean flag = iMasterDao.setEmployeeIsDeactive(emp);
if(flag) {
response.setStatus("Success");
response.setStatusCode("200");
response.setResult("True");
response.setReason("Record deleted successfully");
}else{
response.setStatus("Fail");
response.setStatusCode("200");
response.setResult("False");
}
}else {
response.setStatus("Fail");
response.setStatusCode("500");
response.setResult("False");
response.setReason("# EXCEPTION : " + e.getMessage());
}
}
return response;
}
<小时/>

Dao 实现 -

public boolean isDataExist(Employee emp) {
boolean flag = false;
List<Object[]> tbl1 = session.createQuery("FROM Table1 where emp_id=:id")
.setParameter("id",emp.getId())
.getResultList();

if(!tbl1.isEmpty() && tbl1.size() > 0) {
flag = true;
}

List<Object[]> tbl2 = session.createQuery("FROM Table2 where emp_id=:id")
.setParameter("id",emp.getId())
.getResultList();

if(!tbl2.isEmpty() && tbl2.size() > 0) {
flag = true;
}

List<Object[]> tbl3 = session.createQuery("FROM Table3 where emp_id=:id")
.setParameter("id",emp.getId())
.getResultList();

if(!tbl3.isEmpty() && tbl3.size() > 0) {
flag = true;
}

return flag;
}

public boolean doSoftDelete(Employee emp) {
empDet = session.get(Employee.class, emp.getId());
empDet .setIsActive("N");
session.update(empDet);
}

public boolean doHardDelete(Employee emp) {
empDet = session.get(Employee.class, emp.getId());
session.delete(empDet);
}

无论将添加多少个带有主表引用的事务表,我的代码都应该相应地执行操作(软/硬删除)。

就我而言,每次添加新的事务表并添加主引用时,我都会进行检查,所以我想跳过 isDataExist() 方法并相应地进行删除,我怎样才能更好地做到这一点方式?

请帮助我采取正确的方法来做到这一点。

最佳答案

isDataExist()正文中有大量重复代码方法既难以维护又难以扩展(如果您必须再添加 3 个表,则代码的大小将增加一倍)。最重要的是,逻辑不是最佳的,因为即使第一个表的结果足以返回true,它也会遍历所有表。 .

这是一个简化版本(请注意,我尚未测试代码,可能存在错误,但它应该足以解释这个概念):

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而不是Stringboolean :

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

第二个构建 ResponseStatus和一个 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;
}

并使用switchif-else buildResponse(Status status, String reason) 中的语句方法基于 Status 构建响应类型。

关于java - 如果存在引用则更新行,否则使用 spring boot 删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58522047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com