Spring @Audited 審計(jì)——‘createdBy’,‘createdDate’,‘lastModifiedBy’和‘lastModifiedDate’

原創(chuàng)性聲明:本文完全為筆者原創(chuàng)缸逃,請(qǐng)尊重筆者勞動(dòng)力休讳。轉(zhuǎn)載務(wù)必注明原文地址。

這是一個(gè)很常見的需求 :

例如另锋。簡(jiǎn)書數(shù)據(jù)庫中,文章表(articles)中的某條記錄是被那個(gè)賬號(hào)創(chuàng)建的(@CreateBy)狭归,最后的一次更新是哪個(gè)賬號(hào)干的(@LastModifiedBy)夭坪,以及創(chuàng)建的時(shí)間是什么(@CreateDate),最后更新的時(shí)間又是什么(@LastModifiedDate)过椎?

這既可以作為用戶所需要的字段信息室梅,在一定程度上也是一種操作記錄的體現(xiàn)。當(dāng)然,這樣的功能亡鼠,完全可以自己在CRUD操作的時(shí)候去實(shí)現(xiàn)赏殃,但是秉持著程序的精簡(jiǎn)性和可靠性,用Spring 的@Audited自然是一種更好的方法了间涵。

Spring審計(jì)功能簡(jiǎn)單易用(我的項(xiàng)目建立在Spring boot之上)仁热。

假設(shè)我們的domain包下,有一個(gè)抽象的審計(jì)超類——AbstractAuditingEntity勾哩,其他的實(shí)體類都繼承它抗蠢。


@MappedSuperclass
@Audited
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity {

      @CreatedBy
      @Column(name = "created_by", nullable = false, length = 50, updatable = false)
      @JsonIgnore
      private String createdBy;

      @CreatedDate
      @Column(name = "created_date", nullable = false, updatable = false)
      @JsonIgnore
      private LocalDateTime createdDate = LocalDateTime.now();

      @LastModifiedBy
      @Column(name = "last_modified_by", length = 50)
      @JsonIgnore
      private String lastModifiedBy;

      @LastModifiedDate
      @Column(name = "last_modified_date")
      @JsonIgnore
      private LocalDateTime lastModifiedDate = LocalDateTime.now();

      // 省略對(duì)應(yīng)的 set/get 方法......
}

簡(jiǎn)單講一下類上三個(gè)注解的作用。

@MappedSuperclass API文檔是這么寫的: 指定一個(gè)類思劳,其映射信息應(yīng)用于從其繼承的實(shí)體迅矛。 映射的超類沒有為它定義的單獨(dú)的表。使用MappedSuperclass注釋指定的類可以以與實(shí)體相同的方式進(jìn)行映射敢艰,除了映射將僅應(yīng)用于其子類诬乞,因?yàn)橛成涞某惐旧頉]有表。(谷歌翻譯)翻譯的雖然不是非常順口钠导,但大致還是能看懂的震嫉。意思就是說,應(yīng)用這個(gè)注解的類(比如上面例子的AbstractAuditingEntity)在數(shù)據(jù)庫里是沒有表與它對(duì)應(yīng)的牡属,但是它的屬性(這里的四個(gè)屬性)票堵,將會(huì)被繼承的子類所繼承,并映射到子類在數(shù)據(jù)庫中對(duì)應(yīng)的這四個(gè)字段逮栅。那么顯而易見悴势,這個(gè)注解可以把眾多實(shí)體類的公共屬性提取出來,這也是此處的作用措伐。
@Audited API文檔是這么寫的: 當(dāng)應(yīng)用于類時(shí)特纤,表示其所有屬性都應(yīng)該被審計(jì)。 當(dāng)應(yīng)用于一個(gè)字段時(shí)侥加,表示該字段應(yīng)該被審計(jì)捧存。沒什么好解釋的,谷歌這個(gè)翻譯担败,很6昔穴。
@EntityListeners(AuditingEntityListener.class) 指定要用于實(shí)體或映射超類的回調(diào)偵聽器類。 此注釋可以應(yīng)用于實(shí)體類或映射超類提前。相當(dāng)于給當(dāng)前的超類注冊(cè)一個(gè)監(jiān)聽器吗货,注冊(cè)給誰呢,就是Spring提供的AuditingEntityListener這個(gè)類狈网,從名字上看就大概揣測(cè)一二這個(gè)監(jiān)聽器的作用宙搬,監(jiān)聽一個(gè)實(shí)體創(chuàng)建或更新時(shí)的審計(jì)用的笨腥。

顯然這三個(gè)注解都是必不可少的,當(dāng)然如果不把公共實(shí)體抽取出來勇垛,而是在某個(gè)具體的類上(如Article)使用這些注解和聲明定義這四個(gè)屬性扇雕,那么@MappedSuperclass就沒有必要了。

至于@CreatedBy窥摄、@CreatedDate@LastModifiedBy@LastModifiedDate,那就對(duì)號(hào)入座了础淤。

@JsonIgnore : 忽略改字段的序列化和反序列化崭放。這么做,客戶端將不會(huì)獲得該字段鸽凶。

這么做還是不夠的币砂,如果我們沒有在JPA操作中啟用審計(jì)功能的話。啟用的方法很簡(jiǎn)單玻侥,只需要在主類上加上啟用的注解即可:

@SpringBootApplication
@EnableJpaAuditing //在JPA操作中啟用審計(jì)功能
public class Application 
{
    public static void main( String[] args )
    {
        SpringApplication.run(Application.class, args);
    }
}

跑起來我們會(huì)發(fā)現(xiàn)决摧。createBylastModifiedBy的值并不會(huì)被相應(yīng)地自動(dòng)填上。因此我們還少了一個(gè)步驟——實(shí)現(xiàn)AuditorAware接口凑兰,并實(shí)現(xiàn)getCurrentAuditor方法掌桩,不然程序不知道創(chuàng)建者和最后修改者怎么給值。

@Component
public class SpringSecurityAuditorAware implements AuditorAware<String> {

  @Override
  public String getCurrentAuditor() {
    // TODO 返回當(dāng)前session會(huì)話中的賬戶名即可
  }
}

getCurrentAuditor方法中也體現(xiàn)了記錄createdBylastModifiedBy的策略(包括是保存操作者用戶名姑食,還是電話號(hào)碼或其他信息)波岛,一般情況下,當(dāng)然是返回session中的賬戶信息(通常是賬戶名)音半,因?yàn)榭隙ㄊ沁@個(gè)賬戶修改的對(duì)應(yīng)數(shù)據(jù)则拷。

如此一來,在對(duì)普通實(shí)體類的CRUD操作時(shí)曹鸠,便不用操心某條記錄是誰創(chuàng)建的煌茬、啥時(shí)候創(chuàng)建的,又是誰最后一次更新的彻桃,最后一次更新是啥時(shí)候這樣的破事兒了坛善。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市叛薯,隨后出現(xiàn)的幾起案子浑吟,更是在濱河造成了極大的恐慌,老刑警劉巖耗溜,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件组力,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抖拴,警方通過查閱死者的電腦和手機(jī)燎字,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門腥椒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人候衍,你說我怎么就攤上這事笼蛛。” “怎么了蛉鹿?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵滨砍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我妖异,道長(zhǎng)惋戏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任他膳,我火速辦了婚禮响逢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棕孙。我一直安慰自己舔亭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布蟀俊。 她就那樣靜靜地躺著钦铺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肢预。 梳的紋絲不亂的頭發(fā)上职抡,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音误甚,去河邊找鬼缚甩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窑邦,可吹牛的內(nèi)容都是我干的擅威。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼冈钦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼郊丛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞧筛,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤厉熟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后较幌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揍瑟,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年乍炉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绢片。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滤馍。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖底循,靈堂內(nèi)的尸體忽然破棺而出巢株,到底是詐尸還是另有隱情,我是刑警寧澤熙涤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布阁苞,位于F島的核電站,受9級(jí)特大地震影響祠挫,放射性物質(zhì)發(fā)生泄漏猬错。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一茸歧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧显沈,春花似錦软瞎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至魔慷,卻和暖如春只锭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背院尔。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國打工蜻展, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邀摆。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓纵顾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親栋盹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子施逾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)例获,斷路器汉额,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,826評(píng)論 6 342
  • 此篇翻譯的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤閱讀 6,752評(píng)論 0 21
  • 風(fēng)的那邊埋葬著兩個(gè)詩人一個(gè)熱愛生活 向往幸福用詩篇記錄歲月一個(gè)懷疑世界 傾心死亡用詩篇遺忘過去然而沒有...
    子健閱讀 794評(píng)論 1 7
  • 1.描述 The count-and-say sequence is the sequence of intege...
    YellowLayne閱讀 269評(píng)論 0 0