我有幾個 JPA 物體,每個物體都有一個資料庫用戶列,在該列中我必須存盤對表中特定行進行更改的用戶。
我創建了一個'MappedSuperclass' Bean,所有物體都將從中擴展,這就是 MappedSuperclass。
@MappedSuperclass
public abstract class AuditableBean {
@Column(name = "modifier_user", nullable = false)
private String modifier_user;
// Getters and Setters
}
這是一個從“MappedSuperclass”擴展而來的物體。
@Entity
@Table(name = "nm_area_ref")
public class ServingAreaReferenceBean extends AuditableBean {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "nm_area_ref_id")
private UUID id;
@Column(name = "nm_srv_area_desc", nullable = false)
private String description;
@Column(name = "nm_retired", nullable = false)
private boolean retired;
// Getters and Setters
}
并且,所有的 Bean 都有一個對應的服務方法,用于將資料保存在資料庫中,這是服務類之一(每個服務注入一個用于 CRUD 操作的存盤庫)。
// Service
@Component
public class ServingAreaReferenceBO {
@Inject private ServingAreaReferenceRepository repository; //repository injection
@Inject private CloudContextProvider cloudContextProvider;
public List<ServingAreaReferenceBean> getAllServingAreaReferences() {
return Lists.newArrayList(repository.findAll());
}
public Optional<ServingAreaReferenceBean> findById(UUID id) {
return repository.findById(id);
}
public ServingAreaReferenceBean create(ServingAreaReferenceBean servingAreaReference) {
Optional<CloudContext> cloudContext = Optional.ofNullable(cloudContextProvider.get());// line 1
servingAreaReference.setUpdaterUser(cloudContext.map(CloudContext::getUserId).orElse(null));// line 2
return repository.save(servingAreaReference);// line 3
}
}
// Repository - It extends from CrudRepository (insert, update, delete operations)
@Repository
public interface ServingAreaReferenceRepository extends CrudRepository<ServingAreaReferenceBean, UUID> {
boolean existsByDescription(String description);
boolean existsByDescriptionAndIdIsNot(String description, UUID id);
}
當“repository.save()”(第 3 行)執行時,它成功存盤了用戶,但我將用戶邏輯放在執行保存方法之前(第 1、2 行)。所以我不認為在每個服務上重復這兩行是最好的方法,相反,我想實作一個通用方法或一個通用類,在執行保存方法之前為所有 Bean 物體設定用戶。
那可能嗎?什么是更好的方法?
我想實作這樣的東西,但不知道如何使它通用?
@Component
public class AuditableBeanHandler {
@Inject private CloudContextProvider cloudContextProvider;
public AuditableBean populateAuditInformation(AuditableBean auditableBean) {
Optional<CloudContext> cloudContext = Optional.ofNullable(CloudContextProvider.get());
auditableBean.setUpdaterUser(CloudContext.map(cloudContext::getUserId).orElse(null));
return auditableBean;
}
}
uj5u.com熱心網友回復:
好吧,我的理解是,您必須在物體的每次保存呼叫之前設定用戶:
這可以通過使用稱為“模板方法設計模式”的眾所周知的設計模式來解決。
只需為服務類創建一個父類:
public abstract class AbstractService<T extends AuditableBean> {
public AuditableBean populateAuditInformation(AuditableBean auditableBean) {
Optional<CloudContext> cloudContext = Optional.ofNullable(CloudContextProvider.get());
auditableBean.setLastUpdatedByUser(CloudContext.map(cloudContext::getUserId).orElse(null));
return auditableBean;
}
public absract T save(T areaReference);
public final T create(T t) {
t = populateAuditInformation(t);
return save(t);
}
并在您的服務類中擴展此抽象服務并添加保存方法:
public class AreaReferenceService extends AbstractService<AreaReferenceBean> {
public AreaReferenceBean save(AreaReferenceBean AreaReference) {
return repository.save(AreaReference);
}
}
在呼叫服務方法時,呼叫create()方法。希望這能解決你的問題,你也可以閱讀更多關于模板方法設計模式的資訊。
uj5u.com熱心網友回復:
我認為您與 AuditableBean 非常接近。
添加以下配置以啟用審計:
// Annotate a configuration class with this
@EnableJpaAuditing(auditorAwareRef = "auditAware")
添加這個“auditAware”bean,您需要調整它以匹配您正在使用的任何身份驗證機制。它的唯一目的是回傳經過身份驗證的用戶的用戶名,Spring 將使用它。
@Bean
public AuditorAware<String> auditAware() {
return () -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return Optional.of(authentication.getPrincipal());
};
}
@LastModifiedBy在您的 modified_user 欄位 ( ) 中再添加一個注釋。AuditAware這告訴 Spring,當物體發生更新時,將此欄位設定為從bean回傳的值。
@Column(name = "modifier_user", nullable = false)
@LastModifiedBy
private String modifier_user;
有關可用審計欄位的更多資訊,請參閱Spring Data JPA 檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/416529.html
標籤:
上一篇:使用c繪制圓、線、弧等
