Java 如果存在引用,则更新行,否则使用spring引导删除
需要指引- 如何在没有引用时执行硬删除,在引用可用时执行软删除,此操作应在单个方法中执行 例如。 我有1个主表和3个事务表,主参考在所有3个事务表中都可用。 现在删除主表行时,我必须执行以下操作:如果主表引用可用,则更新主表行;如果没有主表引用,则删除该行 到目前为止,我试着跟随 服务实施-Java 如果存在引用,则更新行,否则使用spring引导删除,java,spring-boot,Java,Spring Boot,需要指引- 如何在没有引用时执行硬删除,在引用可用时执行软删除,此操作应在单个方法中执行 例如。 我有1个主表和3个事务表,主参考在所有3个事务表中都可用。 现在删除主表行时,我必须执行以下操作:如果主表引用可用,则更新主表行;如果没有主表引用,则删除该行 到目前为止,我试着跟随 服务实施- public response doHardOrSoftDelete(Employee emp) { boolean flag = iMasterDao.isDataExist(emp);
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);
}
public boolean isDataExist(员工emp){
布尔标志=假;
List tbl1=session.createQuery(“来自表1,其中emp_id=:id”)
.setParameter(“id”,emp.getId())
.getResultList();
如果(!tbl1.isEmpty()&&tbl1.size()>0){
flag=true;
}
List tbl2=session.createQuery(“来自表2,其中emp_id=:id”)
.setParameter(“id”,emp.getId())
.getResultList();
如果(!tbl2.isEmpty()&&tbl2.size()>0){
flag=true;
}
List tbl3=session.createQuery(“来自表3,其中emp_id=:id”)
.setParameter(“id”,emp.getId())
.getResultList();
如果(!tbl3.isEmpty()&&tbl3.size()>0){
flag=true;
}
返回标志;
}
公共布尔doSoftDelete(员工emp){
empDet=session.get(Employee.class,emp.getId());
empDet.setIsActive(“N”);
更新会议(empDet);
}
公共布尔值doHardDelete(员工emp){
empDet=session.get(Employee.class,emp.getId());
删除(empDet);
}
无论使用主tbl引用添加多少事务表,我的代码都应该相应地执行操作(软/硬删除)
在我的例子中,每次使用主引用添加新的事务表时,我都会进行检查,因此我只想跳过isDataExist()方法并相应地进行删除,如何才能以更好的方式进行
请帮助我找到正确的方法来做同样的事情。在
isDataExist()
方法的主体中有大量重复的代码,这既难以维护,也难以扩展(如果您必须再添加3个表,代码的大小将加倍)。
除此之外,逻辑不是最优的,因为它将遍历所有表,即使第一个表的结果足以返回true
这里是一个简化版本(请注意,我没有测试代码,可能会有错误,但应该足以解释这个概念):
MasterDao
方法更改为返回状态
,而不是字符串
或布尔值
:
公共状态删除员工详细信息(员工){
返回Status.DELETE\u SUCCESS;//或Status.DELETE\u FAIL
}
公共状态停用员工(员工){
返回Status.DEACTIVATE\u SUCCESS;//或Status.DEACTIVATE\u FAIL
}
以下是新的deletemployee()
方法:
公共响应删除员工(员工){
地位;
字符串原因=null;
试一试{
status=masterDao.deleteEmployeeDetails(员工);
}捕获(例外e){
如果(isConstraintViolationException(e)){
status=masterDao.deactivateeemployee(员工);
}否则{
status=status.ERROR;
reason=“#异常:”+e.getMessage();
}
}
返回buildResponse(状态、原因);
}
它使用两个简单的实用程序方法(您可以使这些方法成为静态的或导出到实用程序类,因为它们不依赖于内部状态)
首先检查引发异常的根本原因是否为ConstraintViolationException
:
private boolean isConstraintViolationException(Throwable-Throwable){
可丢弃根=可丢弃;
while(root!=null&!(ConstraintViolationException的根实例)){
root=root.getCause();
}
返回根!=null;
}
第二种方法根据状态和原因构建响应
:
private Response buildResponse(状态、字符串原因){
响应=新响应();
response.setStatus(status.getStatus());
response.setStatusCode(status.getStatusCode());
response.setResult(status.getResult());
如果(原因!=null){
响应。设置原因(reason);
}否则{
response.setReason(status.getReason());
}
返回响应;
}
如果您不希望在状态枚举
中加载默认的响应
消息,您可以将其从额外信息中删除:
公共枚举状态{
删除成功、删除失败、停用成功、停用失败、错误;
}
并使用buildResponse(状态状态,字符串原因)
方法中的switch
或if-else
语句根据状态
类型构建响应。@MartingBG-感谢您的回复和最佳解决方案。给定的解决方案优化了代码,但每次将主实体映射到事务实体时,都必须显式地提到表名。所以为了避免这种情况,我尝试了另一种方法,它确实有效,但我不知道它是否是正确的方法,请帮助。请看我编辑的帖子'
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;
}