hibernate 中的拦截器EmptyInterceptor接口功能

Interceptor接口提供了从会话(session)回调(callback)应用程序(application)的机制, 这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其 属性。一个可能的用途,就是用来跟踪审核(auditing)信息。例如:下面的这个拦截器,会在一个实现了 Auditable接口的对象被创建时自动地设置createTimestamp属性,并在实现了 Auditable接口的对象被更新时,同步更新lastUpdateTimestamp属性。 

 

你可以直接实现Interceptor接口,也可以(最好)继承自EmptyInterceptor。 

 

package org.hibernate.test;

 

import java.io.Serializable;

import java.util.Date;

import java.util.Iterator;

 

import org.hibernate.EmptyInterceptor;

import org.hibernate.Transaction;

import org.hibernate.type.Type;

 

public class AuditInterceptor extends EmptyInterceptor {

 

    private int updates;

    private int creates;

    private int loads;

 

    public void onDelete(Object entity,

                         Serializable id,

                         Object[] state,

                         String[] propertyNames,

                         Type[] types) {

        // do nothing

    }

 

    public boolean onFlushDirty(Object entity,

                                Serializable id,

                                Object[] currentState,

                                Object[] previousState,

                                String[] propertyNames,

                                Type[] types) {

 

        if ( entity instanceof Auditable ) {

            updates++;

            for ( int i=0; i < propertyNames.length; i++ ) {

                if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {

                    currentState[i] = new Date();

                    return true;

                }

            }

        }

        return false;

    }

 

    public boolean onLoad(Object entity,

                          Serializable id,

                          Object[] state,

                          String[] propertyNames,

                          Type[] types) {

        if ( entity instanceof Auditable ) {

            loads++;

        }

        return false;

    }

 

    public boolean onSave(Object entity,

                          Serializable id,

                          Object[] state,

                          String[] propertyNames,

                          Type[] types) {

 

        if ( entity instanceof Auditable ) {

            creates++;

            for ( int i=0; i<propertyNames.length; i++ ) {

                if ( "createTimestamp".equals( propertyNames[i] ) ) {

                    state[i] = new Date();

                    return true;

                }

            }

        }

        return false;

    }

 

    public void afterTransactionCompletion(Transaction tx) {

        if ( tx.wasCommitted() ) {

            System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);

        }

        updates=0;

        creates=0;

        loads=0;

    }

 

}

拦截器可以有两种:Session范围内的,和SessionFactory范围内的。 

 

当使用某个重载的SessionFactory.openSession()使用Interceptor作为参数调用打开一个session的时候,就指定了Session范围内的拦截器。 

 

Session session = sf.openSession( new AuditInterceptor() );

 

 

 

或在配置文件中加:

<bean id="sessionFactory" class="cn.sh.cares.framework.spring.annotationSessionFactoryBean">

<property name="dataSource" ref="ppcDataSource"/>

<!--<property name="lobHandler" ref="lobHandler"/>-->

<property name="annotatedClassesLocations">

<list>

<value>classpath*:</value>

</list>

</property>

<property name="hbmLocations">

<list>

<value>classpath*:</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">cn.sh.cares.framework.dao.hibernate.OracleDialect</prop>

<prop key="hibernate.format_sql">true</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.use_sql_comments">false</prop>

<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

<prop key="hibernate.cache.use_query_cache">true</prop>

<prop key="hibernate.cache.use_second_level_cache">true</prop>

<prop key="hibernate.jdbc.batch_size">20</prop>

<prop key="hibernate.jdbc.fetch_size">20</prop>

</props>

</property>

<property name="entityInterceptor">

<bean id ="auditInterceptor" class="cn.sh.cares.framework.dao.hibernate.AuditInterceptor" />

</property>

### Spring Boot 中 Hibernate 自定义拦截器实现与配置 在 Spring Boot 应用程序中集成 Hibernate 并创建自定义拦截器可以通过扩展 `EmptyInterceptor` 或者实现 `Interceptor` 接口来完成。这允许开发者捕获并修改持久化操作期间发生的事件。 #### 创建自定义拦截器类 为了构建一个自定义拦截器,可以继承 `org.hibernate.EmptyInterceptor` 类,并重写所需的方法: ```java import org.hibernate.EmptyInterceptor; import java.io.Serializable; public class CustomAuditLogInterceptor extends EmptyInterceptor { @Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { // 实现保存前逻辑处理 return super.onSave(entity, id, state, propertyNames, types); } @Override public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { // 实现在删除实体之前执行的操作 super.onDelete(entity, id, state, propertyNames, types); } } ``` 此代码片段展示了如何通过覆盖特定方法来自定义行为[^1]。 #### 配置自定义拦截器 为了让应用程序知道要使用哪个拦截器,在应用上下文中注册该拦截器是必要的。一种方式是在主应用程序类上添加如下属性设置: ```properties spring.jpa.properties.hibernate.ejb.interceptor=com.example.CustomAuditLogInterceptor ``` 另一种更灵活的方式是利用 Java Config 来注入 Bean 定义: ```java @Configuration public class AppConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory( DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) { final var factory = new LocalContainerEntityManagerFactoryBean(); factory.setDataSource(dataSource); factory.setJpaVendorAdapter(jpaVendorAdapter); Properties properties = new Properties(); properties.put("hibernate.ejb.interceptor", "com.example.CustomAuditLogInterceptor"); factory.setJpaProperties(properties); return factory; } } ``` 上述配置确保每次启动时都会加载指定路径下的自定义拦截器实例[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值