1
0

feat(web): 实体软删除实现

This commit is contained in:
2024-12-01 15:20:39 +08:00
parent e134006794
commit 37267b4c7c
8 changed files with 141 additions and 8 deletions

View File

@@ -1,6 +1,11 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="47" name="Java" />
</Languages>
</inspection_tool>
<inspection_tool class="HttpUrlsUsage" enabled="false" level="WEAK WARNING" enabled_by_default="false" /> <inspection_tool class="HttpUrlsUsage" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile> </profile>
</component> </component>

View File

@@ -0,0 +1,27 @@
package com.eshore.gringotts.web.domain.base.entity;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* 实体类公共字段
*
* @author lanyuanxiaoyao
* @date 2024-11-20
*/
@Getter
@Setter
@ToString(callSuper = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class LogicDeleteEntity extends SimpleEntity {
public static final String LOGIC_DELETE_CLAUSE = "deleted = false";
@Column(nullable = false)
private Boolean deleted = false;
}

View File

@@ -0,0 +1,27 @@
package com.eshore.gringotts.web.domain.base.entity;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* 实体类公共字段
*
* @author lanyuanxiaoyao
* @date 2024-11-20
*/
@Getter
@Setter
@ToString(callSuper = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class LogicDeleteIdOnlyEntity extends IdOnlyEntity {
public static final String LOGIC_DELETE_CLAUSE = "deleted = false";
@Column(nullable = false)
private Boolean deleted = false;
}

View File

@@ -0,0 +1,50 @@
package com.eshore.gringotts.web.domain.base.service;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.user.service.UserService;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
/**
* @author lanyuanxiaoyao
* @date 2024-11-21
*/
@Slf4j
public abstract class LogicDeleteService<ENTITY extends LogicDeleteEntity> extends SimpleServiceSupport<ENTITY> {
private final EntityManager manager;
public LogicDeleteService(SimpleRepository<ENTITY, Long> repository, UserService userService, EntityManager manager) {
super(repository, userService);
this.manager = manager;
}
@Override
protected ImmutableList<Predicate> extraListPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.of(builder.equal(root.get("deleted"), false));
}
@Override
protected ImmutableList<Predicate> extraDetailPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.of(builder.equal(root.get("deleted"), false));
}
@Transactional(rollbackOn = Throwable.class)
@Override
public void remove(Long id) {
String entityName = ClassUtil.getTypeArgument(this.getClass()).getSimpleName();
Query query = manager.createQuery(StrUtil.format("update {} entity set deleted=true where id=?1", entityName));
query.setParameter(1, id);
query.executeUpdate();
}
}

View File

@@ -9,7 +9,10 @@ import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.user.entity.User; import com.eshore.gringotts.web.domain.user.entity.User;
import com.eshore.gringotts.web.domain.user.service.UserService; import com.eshore.gringotts.web.domain.user.service.UserService;
import java.util.Optional; import java.util.Optional;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists; import org.eclipse.collections.api.factory.Lists;
@@ -24,8 +27,8 @@ import org.springframework.data.domain.Sort;
*/ */
@Slf4j @Slf4j
public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implements SimpleService<ENTITY> { public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implements SimpleService<ENTITY> {
private final SimpleRepository<ENTITY, Long> repository; protected final SimpleRepository<ENTITY, Long> repository;
private final UserService userService; protected final UserService userService;
public SimpleServiceSupport(SimpleRepository<ENTITY, Long> repository, UserService userService) { public SimpleServiceSupport(SimpleRepository<ENTITY, Long> repository, UserService userService) {
this.repository = repository; this.repository = repository;
@@ -64,6 +67,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) { if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user)); predicates.add(builder.equal(root.get("createdUser"), user));
} }
predicates.addAllIterable(extraListPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()])); return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}, },
Sort.by("createdTime").descending() Sort.by("createdTime").descending()
@@ -81,12 +85,17 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) { if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user)); predicates.add(builder.equal(root.get("createdUser"), user));
} }
predicates.addAllIterable(extraListPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()])); return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}, },
Sort.by("createdTime").descending() Sort.by("createdTime").descending()
)); ));
} }
protected ImmutableList<Predicate> extraListPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.empty();
}
@Override @Override
public Optional<ENTITY> detailOptional(Long id) { public Optional<ENTITY> detailOptional(Long id) {
if (ObjectUtil.isNull(id)) { if (ObjectUtil.isNull(id)) {
@@ -101,11 +110,16 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) { if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user)); predicates.add(builder.equal(root.get("createdUser"), user));
} }
predicates.addAllIterable(extraDetailPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()])); return builder.and(predicates.toArray(new Predicate[predicates.size()]));
} }
); );
} }
protected ImmutableList<Predicate> extraDetailPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.empty();
}
@Override @Override
public ENTITY detail(Long id) { public ENTITY detail(Long id) {
return detailOrNull(id); return detailOrNull(id);

View File

@@ -1,7 +1,7 @@
package com.eshore.gringotts.web.domain.confirmation.entity; package com.eshore.gringotts.web.domain.confirmation.entity;
import com.eshore.gringotts.core.Constants; import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.resource.entity.DataResource; import com.eshore.gringotts.web.domain.resource.entity.DataResource;
import com.eshore.gringotts.web.domain.upload.entity.DataFile; import com.eshore.gringotts.web.domain.upload.entity.DataFile;
import java.util.Set; import java.util.Set;
@@ -25,6 +25,9 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.WhereJoinTable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/** /**
@@ -50,9 +53,12 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@NamedAttributeNode(value = "createdUser"), @NamedAttributeNode(value = "createdUser"),
@NamedAttributeNode(value = "modifiedUser"), @NamedAttributeNode(value = "modifiedUser"),
}) })
public class Confirmation extends SimpleEntity { @SQLDelete(sql = "update " + Constants.TABLE_PREFIX + "confirmation" + " set deleted = true where id = ?")
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
public class Confirmation extends LogicDeleteEntity {
@OneToOne(fetch = FetchType.EAGER) @OneToOne(fetch = FetchType.EAGER)
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@WhereJoinTable(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private DataResource target; private DataResource target;
private String description; private String description;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)

View File

@@ -2,7 +2,7 @@ package com.eshore.gringotts.web.domain.resource.entity;
import com.eshore.gringotts.core.Constants; import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.authentication.entity.Authentication; import com.eshore.gringotts.web.domain.authentication.entity.Authentication;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.confirmation.entity.Confirmation; import com.eshore.gringotts.web.domain.confirmation.entity.Confirmation;
import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat; import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat;
import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType; import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType;
@@ -25,6 +25,8 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter @Getter
@@ -48,7 +50,9 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@NamedAttributeNode(value = "createdUser"), @NamedAttributeNode(value = "createdUser"),
@NamedAttributeNode(value = "modifiedUser"), @NamedAttributeNode(value = "modifiedUser"),
}) })
public class DataResource extends SimpleEntity { @SQLDelete(sql = "update " + Constants.TABLE_PREFIX + "data_resource" + " set deleted = true where id = ?")
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
public class DataResource extends LogicDeleteEntity {
@Column(nullable = false) @Column(nullable = false)
private String name; private String name;
private String description; private String description;

View File

@@ -1,7 +1,7 @@
package com.eshore.gringotts.web.domain.resource.entity.type; package com.eshore.gringotts.web.domain.resource.entity.type;
import com.eshore.gringotts.core.Constants; import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.base.entity.IdOnlyEntity; import com.eshore.gringotts.web.domain.base.entity.LogicDeleteIdOnlyEntity;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
@@ -22,7 +22,7 @@ import lombok.ToString;
@Entity @Entity
@Table(name = Constants.TABLE_PREFIX + "resource_type") @Table(name = Constants.TABLE_PREFIX + "resource_type")
@Inheritance(strategy = InheritanceType.JOINED) @Inheritance(strategy = InheritanceType.JOINED)
public abstract class ResourceType extends IdOnlyEntity { public abstract class ResourceType extends LogicDeleteIdOnlyEntity {
public abstract Type getResourceType(); public abstract Type getResourceType();
public enum Type { public enum Type {