最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot使用Hibernate攔截器實現(xiàn)時間自動注入的操作代碼

 更新時間:2022年10月10日 10:18:13   作者:zhuzZi  
這篇文章主要介紹了SpringBoot使用Hibernate攔截器實現(xiàn)時間自動注入的操作代碼,主要包括hibernate攔截器的相關(guān)知識,結(jié)合實例代碼給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

  最近項目有個改動:另一個系統(tǒng)根據(jù)更新時間戳來拉取本系統(tǒng)數(shù)據(jù)。這就要求基本上所有的數(shù)據(jù)表都要及時更新時間戳。以前的方式是在新增數(shù)據(jù)或者修改數(shù)據(jù)時手動調(diào)用setProperty(TimeStamp),因為沒有用到這兩個字段加上每個人的編碼習(xí)慣不同,有時候沒設(shè)置createTime或者updateTime,可能存在遺漏,導(dǎo)致數(shù)據(jù)庫中有的時間戳默認(rèn)值0。

前提:本系統(tǒng)時間戳在數(shù)據(jù)庫類型為int,長度為int默認(rèn)值,存儲示例:1665295775,Java類型Integer,單位: /s

  因為沒怎么使用過Hibernate框架,就想Hibernate有沒有MybatisPlus一樣的自動填充功能呢?查了一下還真有日期相關(guān)的注解:@Temporal(TemporalType.XXX),但是對應(yīng)Java的類型為:java.sql.Date,java.sql.Time,java.sql.Timestamp,數(shù)據(jù)庫的類型為時間相關(guān)的類型:date,time,datetime,timestamp,在不改動歷史數(shù)據(jù)表字段類型的情況下,只能尋求其它方式。

Hibernate攔截器:

  • Interceptor接口:

允許用戶代碼檢查和/或更改屬性值。檢查發(fā)生在屬性值寫入之前和從數(shù)據(jù)庫中讀取之后。 SessionFactory可能有一個Interceptor實例,或者可能為每個Session指定一個新實例。無論使用哪種方法,如果Session要可序列化,則攔截器必須是可序列化的。這意味著SessionFactory范圍的攔截器應(yīng)該實現(xiàn)readResolve() 。 Session不能從回調(diào)中調(diào)用(回調(diào)也不能導(dǎo)致集合或代理被延遲初始化)。與其直接實現(xiàn)此接口,不如繼承EmptyInterceptor并僅覆蓋感興趣的回調(diào)方法。

/**
在刷新期間檢測到對象臟時調(diào)用。攔截器可能會修改檢測到的currentState ,這將被傳播到數(shù)據(jù)庫和持久對象。
請注意,并非所有刷新都以與數(shù)據(jù)庫的實際同步結(jié)束,在這種情況下,新的currentState將傳播到對象,但不一定(立即)傳播到數(shù)據(jù)庫。
強烈建議攔截器不要修改previousState 。
*/
onFlushDirty():
/**
在保存對象之前調(diào)用。攔截器可能會修改狀態(tài),該狀態(tài)將用于 SQL INSERT并傳播到持久對象。
*/
onSave():

那我們?nèi)mptyInterceptor看一下。

  • EmptyInterceptor類:

一個什么都不做的攔截器。可用作應(yīng)用程序定義的自定義攔截器的基類 。

參看上面接口的方法描述,我們只需要繼承EmptyInterceptor并重寫onSave()和onFlushDirty()兩個方法,來分別實現(xiàn)保存(SQL INSERT)更新(SQL UPDATE)即可。Hibernate在檢測到save和update操作時先執(zhí)行自定義邏輯。

代碼實現(xiàn)

看完了攔截器相關(guān),來實現(xiàn)一下代碼,如下:
為了控制每個DDO的行為,可以設(shè)計一個BaseEntityControl接口

/**
 * 數(shù)據(jù)的頂層接口
 */
public interface BaseEntityControl{

	/**
	可以加入其它邏輯
	/

    /**
     * 控制是否需要自動寫入createTime和updateTime
     * @return
     */
    default boolean writeTimeStamp() {
        return true;
    }
}
import com.xx.xxx.BaseEntityControl;
import java.io.Serializable;

/**
 * Interceptor for entity audits.
 */
public class AuditInterceptor extends EmptyInterceptor {

    /**
     * Serial version UID
     */
    private static final long serialVersionUID = 6892420119984901561L;

    /**
     * @see org.hibernate.Interceptor#onFlushDirty(Object, Serializable, Object[], Object[], String[], Type[])
     */
    @Override
    public boolean onFlushDirty(final Object entity, final Serializable id, final Object[] currentState,
            final Object[] previousState, final String[] propertyNames, final Type[] types) {
        if (entity instanceof BaseEntityControl) {
            if (!((BaseEntityControl) entity).writeTimeStamp()) {
                return false;
            }
            for (int i = 0; i < propertyNames.length; i++) {
                if ("updateTime".equals(propertyNames[i])) {
                    currentState[i] = (int) (System.currentTimeMillis() / 1000);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @see org.hibernate.Interceptor#onSave(Object, Serializable, Object[], String[], Type[])
     */
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if (entity instanceof BaseEntityControl) {
            if (!((BaseEntityControl) entity).writeTimeStamp()) {
                return false;
            }
            boolean crtModify = false;
            boolean uptModify = false;
            int i = 0;
            while (true) {
                if (i >= propertyNames.length) {
                    if (crtModify || uptModify) {
                        return true;
                    }
                    break;
                }

                if ("createTime".equals(propertyNames[i])) {
                    crtModify = true;
                    state[i] = (int) (System.currentTimeMillis() / 1000L);
                }

                if ("updateTime".equals(propertyNames[i])) {
                    uptModify = true;
                    state[i] = (int) (System.currentTimeMillis() / 1000L);
                }
                ++i;
            }
        }
        return false;
    }
}

將自定義Interceptor配置到session factory

在session factory配置類中將

public class xxxConfig {
	...
	public FactoryBean<SessionFactory> getSessionFactory() {
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setEntityInterceptor(new AuditInterceptor());
		...
	}
	...
}

對比測試

4.0.9:加入攔截器之前
4.3.1:加入攔截器之后

單個對象20個property情況下:

到此這篇關(guān)于SpringBoot使用Hibernate攔截器實現(xiàn)時間自動注入的操作代碼的文章就介紹到這了,更多相關(guān)SpringBoot使用Hibernate攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JDK集合源碼之解析TreeMap(二)

    JDK集合源碼之解析TreeMap(二)

    下面小編就為大家?guī)硪黄獪\談java中的TreeMap 排序與TreeSet 排序。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-07-07
  • Springmvc調(diào)用存儲過程,并返回存儲過程返還的數(shù)據(jù)方式

    Springmvc調(diào)用存儲過程,并返回存儲過程返還的數(shù)據(jù)方式

    這篇文章主要介紹了Springmvc調(diào)用存儲過程,并返回存儲過程返還的數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java Pattern與Matcher字符串匹配案例詳解

    Java Pattern與Matcher字符串匹配案例詳解

    這篇文章主要介紹了Java Pattern與Matcher字符串匹配案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • ThreadLocal的內(nèi)存泄露問題

    ThreadLocal的內(nèi)存泄露問題

    這篇文章主要介紹了Java中ThreadLocal的內(nèi)存泄露問題,以及為什么會出現(xiàn)內(nèi)存泄漏,感興趣的小伙伴可以參考閱讀
    2023-03-03
  • java easyUI實現(xiàn)自定義網(wǎng)格視圖實例代碼

    java easyUI實現(xiàn)自定義網(wǎng)格視圖實例代碼

    這篇文章主要給大家介紹了關(guān)于java easyUI實現(xiàn)自定義網(wǎng)格視圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • java實現(xiàn)KFC點餐小程序

    java實現(xiàn)KFC點餐小程序

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)KFC點餐系統(tǒng)小程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 淺談@PostConstruct不被調(diào)用的原因

    淺談@PostConstruct不被調(diào)用的原因

    這篇文章主要介紹了淺談@PostConstruct不被調(diào)用的原因及分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java彈幕小游戲1.0版本

    java彈幕小游戲1.0版本

    這篇文章主要為大家詳細(xì)介紹了java彈幕小游戲1.0版本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eureka.server不存在問題

    解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eure

    這篇文章主要介紹了解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eureka.server不存在問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • SpringBoot使用MapStruct生成映射代碼的示例詳解

    SpringBoot使用MapStruct生成映射代碼的示例詳解

    MapStruct 是一個用于 Java 的代碼生成器,專門用于生成類型安全的 bean 映射代碼,它通過注解處理器在編譯時生成映射代碼,從而避免了運行時的性能開銷和潛在的錯誤,本文給大家介紹了SpringBoot使用MapStruct生成映射代碼的示例,需要的朋友可以參考下
    2024-11-11

最新評論

抚顺县| 丰都县| 思南县| 高州市| 三门峡市| 五常市| 开江县| 鄂托克旗| 麻城市| 三门县| 凤城市| 辽阳市| 讷河市| 平遥县| 松江区| 富川| 宁强县| 南宫市| 运城市| 堆龙德庆县| 井陉县| 兴仁县| 巴彦淖尔市| 叶城县| 鸡东县| 广州市| 堆龙德庆县| 尉氏县| 尼玛县| 阿鲁科尔沁旗| 乌拉特前旗| 泸定县| 冀州市| 溧阳市| 登封市| 得荣县| 谢通门县| 卫辉市| 高青县| 茂名市| 潍坊市|