欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

Hibernate攔截器:

  • Interceptor接口:

允許用戶代碼檢查和/或更改屬性值。檢查發(fā)生在屬性值寫入之前和從數(shù)據(jù)庫中讀取之后。 SessionFactory可能有一個Interceptor實例,或者可能為每個Session指定一個新實例。無論使用哪種方法,如果Session要可序列化,則攔截器必須是可序列化的。這意味著SessionFactory范圍的攔截器應該實現(xiàn)readResolve() 。 Session不能從回調(diào)中調(diào)用(回調(dià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類:

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

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

代碼實現(xiàn)

看完了攔截器相關,來實現(xiàn)一下代碼,如下:
為了控制每個DDO的行為,可以設計一個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情況下:

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

相關文章

  • java調(diào)用WebService服務的四種方法總結(jié)

    java調(diào)用WebService服務的四種方法總結(jié)

    WebService是一種跨編程語言、跨操作系統(tǒng)平臺的遠程調(diào)用技術,已存在很多年了,很多接口也都是通過WebService方式來發(fā)布的,下面這篇文章主要給大家介紹了關于java調(diào)用WebService服務的四種方法,需要的朋友可以參考下
    2021-11-11
  • druid連接池的參數(shù)配置示例全面解析

    druid連接池的參數(shù)配置示例全面解析

    這篇文章主要為大家介紹了druid連接池的參數(shù)配置示例全面解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • LoggingEventAsyncDisruptorAppender類執(zhí)行流程源碼解讀

    LoggingEventAsyncDisruptorAppender類執(zhí)行流程源碼解讀

    這篇文章主要介紹了LoggingEventAsyncDisruptorAppender類執(zhí)行流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • java猜數(shù)字小游戲案例

    java猜數(shù)字小游戲案例

    這篇文章主要為大家詳細介紹了java猜數(shù)字小游戲案例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Netty粘包拆包問題解決方案

    Netty粘包拆包問題解決方案

    這篇文章主要介紹了Netty粘包拆包問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • 詳解IDEA啟動多個微服務的配置方法

    詳解IDEA啟動多個微服務的配置方法

    這篇文章主要介紹了詳解IDEA啟動多個微服務的配置方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • 使用純Java實現(xiàn)一個WebSSH項目的示例代碼

    使用純Java實現(xiàn)一個WebSSH項目的示例代碼

    這篇文章主要介紹了使用純Java實現(xiàn)一個WebSSH項目,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • javax.management.InvalidApplicationException的問題解決

    javax.management.InvalidApplicationException的問題解決

    javax.management.InvalidApplicationException是與Java Management Extensions (JMX) API相關的一個常見異常,本文主要介紹了javax.management.InvalidApplicationException的問題解決,感興趣的可以了解一下
    2024-08-08
  • 使用多個servlet時Spring security需要指明路由匹配策略問題

    使用多個servlet時Spring security需要指明路由匹配策略問題

    這篇文章主要介紹了使用多個servlet時Spring security需要指明路由匹配策略問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java實現(xiàn)手寫一個線程池的示例代碼

    Java實現(xiàn)手寫一個線程池的示例代碼

    線程池技術想必大家都不陌生把,相信在平時的工作中沒有少用,而且這也是面試頻率非常高的一個知識點,那么大家知道它的實現(xiàn)原理和細節(jié)嗎?本文就來通過手寫一個簡單的線程池框架,去掌握線程池的基本原理,感興趣的可以學習一下
    2022-10-10

最新評論