利用SpringDataJPA開(kāi)啟審計(jì)功能,自動(dòng)保存操作人操作時(shí)間
有些業(yè)務(wù)數(shù)據(jù)對(duì)數(shù)據(jù)的創(chuàng)建、最后更新時(shí)間以及創(chuàng)建、最后操作人進(jìn)行記錄。如果使用Spring Data Jpa做數(shù)據(jù)新增或更新,可實(shí)現(xiàn)自動(dòng)保存這些信息而不需要顯示設(shè)置對(duì)應(yīng)字段的值,可通過(guò)以下步驟進(jìn)行配置。
1 相關(guān)注解
實(shí)現(xiàn)自動(dòng)記錄上述信息主要有5個(gè)注解
@EnableJpaAuditing
:審計(jì)功能開(kāi)關(guān)@CreatedBy
:標(biāo)記數(shù)據(jù)創(chuàng)建者屬性@LastModifiedBy
:標(biāo)記數(shù)據(jù)最近一次修改者屬性@CreatedDate
:標(biāo)記數(shù)據(jù)創(chuàng)建日期屬性@LastModifiedDate
:標(biāo)記數(shù)據(jù)最近一次修改日期屬性
2 實(shí)現(xiàn)過(guò)程
2.1 依賴引用
使用Spring Data JPA要引用依賴spring-boot-starter-data-jpa,gradle引用方式如下
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2.2 實(shí)體類(lèi)標(biāo)記審計(jì)屬性
案例使用User實(shí)體演示過(guò)程,需要在實(shí)體對(duì)應(yīng)的字段上添加對(duì)應(yīng)的注解表示是審計(jì)屬性,另外需要在實(shí)體類(lèi)上開(kāi)啟審計(jì)監(jiān)聽(tīng),如下:
@Entity @Table(name = "h_user") @EntityListeners({AuditingEntityListener.class})//開(kāi)啟審計(jì)監(jiān)聽(tīng) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; //保存創(chuàng)建人的字段 @CreatedBy @Column(name = "created_by") private String createdBy; //保存最近修改人的字段 @LastModifiedBy @Column(name = "last_modified_by") private String lastModifiedBy; //保存創(chuàng)建時(shí)間的字段 @CreatedDate @Column(name = "created_date") //保存最近修改日期的字段 private Date createdDate; @LastModifiedDate @Column(name = "last_modified_date") private Date lastModifiedDate; private String realName; private String username; private String mobile; private String email; private String password; private Integer flag; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCreatedBy() { return createdBy; } public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } public String getLastModifiedBy() { return lastModifiedBy; } public void setLastModifiedBy(String lastModifiedBy) { this.lastModifiedBy = lastModifiedBy; } public Date getCreatedDate() { return createdDate; } public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; } public Date getLastModifiedDate() { return lastModifiedDate; } public void setLastModifiedDate(Date lastModifiedDate) { this.lastModifiedDate = lastModifiedDate; } public String getRealName() { return this.realName; } public void setRealName(String realName) { this.realName = realName; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @JsonIgnore public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getFlag() { return flag; } public void setFlag(Integer flag) { this.flag = flag; } }
上述User實(shí)體對(duì)應(yīng)數(shù)據(jù)表定義如下:
create table h_user ( id int auto_increment primary key, username varchar(30) default '' not null comment '登錄用戶名', real_name varchar(30) default '' null comment '真實(shí)姓名', mobile varchar(25) default '' null comment '手機(jī)號(hào)碼', email varchar(30) default '' null comment '郵箱', password varchar(100) default '' null comment '加密密碼', flag int default '0' null comment '用戶標(biāo)記', created_by varchar(50) default 'HSystem' null comment '創(chuàng)建人', created_date datetime default CURRENT_TIMESTAMP not null, last_modified_by varchar(30) default 'HSystem' null comment '修改人', last_modified_date datetime default CURRENT_TIMESTAMP not null, constraint user_username_uindex unique (username) ) engine=InnoDB;
2.3 審計(jì)自定義操作
當(dāng)對(duì)實(shí)體有新增或保存操作時(shí),系統(tǒng)會(huì)自動(dòng)獲取操作時(shí)的系統(tǒng)時(shí)間作為創(chuàng)建時(shí)間和修改時(shí)間。
對(duì)于創(chuàng)建者或最后修改這,審計(jì)過(guò)程會(huì)獲取當(dāng)前登錄系統(tǒng)的用戶信息,當(dāng)未登錄的情況下,需要指定默認(rèn)操作,可通過(guò)實(shí)現(xiàn)AuditorAware類(lèi)來(lái)實(shí)現(xiàn)。
下面代碼在未獲取到用戶信息時(shí)返回HSystem表示默認(rèn)為系統(tǒng)操作。
@Configuration public class SpringSecurityAuditorAware implements AuditorAware<String> { final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public Optional<String> getCurrentAuditor() { try { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication instanceof AnonymousAuthenticationToken) { return Optional.of("HSystem"); } else { if (authentication == null) { return Optional.of("HSystem"); } User user = (User) authentication.getPrincipal(); return Optional.of(user.getUsername()); } } catch (Exception ex) { logger.error("get user Authentication failed: " + ex.getMessage(), ex); return Optional.of("HSystem"); } } }
2.4 應(yīng)用開(kāi)啟審計(jì)功能
在應(yīng)用程序入口類(lèi)添加注解@EnableJpaAuditing開(kāi)啟審計(jì)功能,如下
@SpringBootApplication //啟用JPA審計(jì)功能,自動(dòng)填充@CreateDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy注解的字段 @EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware") public class HBackendApplication { public static void main(String[] args) { SpringApplication.run(HBackendApplication.class, args); } }
注意:如果系統(tǒng)中有多個(gè)審計(jì)實(shí)現(xiàn),需要指定Bean的名稱,上面案例中使用名稱為springSecurityAuditorAware的bean。
2.5 實(shí)體操作
定義User實(shí)體類(lèi)的JPA操作接口UserRepository如下
@Repository public interface UserRepository extends PagingAndSortingRepository<User, Integer>, JpaRepository<User, Integer> { }
例如創(chuàng)建用戶時(shí)代碼如下,不需要顯示設(shè)置上面提到的4個(gè)屬性
User user = new User(); user.setUsername(username.trim()); user.setPassword(this.passwordEncoder.encode(password)); user.setEmail("crane.liu@qq.com"); user.setFlag(0); user.setMobile("18988888888"); user.setRealName(username); this.userRepository.save(user);
當(dāng)使用UserRepository對(duì)User類(lèi)進(jìn)行保存時(shí),系統(tǒng)會(huì)自動(dòng)記錄數(shù)據(jù)的審計(jì)屬性值。
最終效果如下:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot上傳臨時(shí)文件被刪除引起報(bào)錯(cuò)的解決
這篇文章主要介紹了SpringBoot上傳臨時(shí)文件被刪除引起報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringCloud學(xué)習(xí)筆記之Feign遠(yuǎn)程調(diào)用
Feign是一個(gè)聲明式的http客戶端。其作用就是幫助我們優(yōu)雅的實(shí)現(xiàn)http請(qǐng)求的發(fā)送。本文將具體為大家介紹一下Feign的遠(yuǎn)程調(diào)用,感興趣的可以了解一下2021-12-12JAVA基礎(chǔ)之基本數(shù)據(jù)類(lèi)型全面解析
下面小編就為大家?guī)?lái)一篇JAVA基礎(chǔ)之基本數(shù)據(jù)類(lèi)型全面解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07一篇文章帶你入門(mén)java網(wǎng)絡(luò)編程
網(wǎng)絡(luò)編程是指編寫(xiě)運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過(guò)網(wǎng)絡(luò)連接起來(lái)。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來(lái)實(shí)現(xiàn)TCP和UDP的Socket的編程,來(lái)讓讀者更好的了解其原理2021-08-08Spring Data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的兩種方法
本篇文章主要介紹了Spring Data JPA實(shí)現(xiàn)動(dòng)態(tài)查詢的兩種方法,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04SpringBoot如何使用@RequestBody進(jìn)行數(shù)據(jù)校驗(yàn)
在Web開(kāi)發(fā)中,前臺(tái)向后臺(tái)發(fā)送數(shù)據(jù)是非常常見(jiàn)的場(chǎng)景,而在SpringBoot框架中,我們通常使用@RequestBody注解來(lái)接收前臺(tái)發(fā)送的?JSON數(shù)據(jù),并將其轉(zhuǎn)化為Java對(duì)象,本文將介紹如何在?SpringBoot?中使用?@RequestBody?進(jìn)行數(shù)據(jù)校驗(yàn)2023-06-06