Hibernate(39)Hibernate中如何使用拦截器?

Hibernate中的拦截器

Hibernate拦截器(Interceptor)是一个允许你在实体对象的生命周期事件(如保存、更新、删除等)发生时插入自定义逻辑的机制。通过实现Interceptor接口,可以在这些事件触发时执行特定的操作。

使用拦截器的示例代码

步骤一:创建一个拦截器类

首先,我们需要创建一个实现Interceptor接口的类。这个类将包含我们希望在实体对象生命周期事件发生时执行的逻辑。

java 复制代码
package com.example.interceptor;

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

import java.io.Serializable;
import java.util.Iterator;

public class CustomInterceptor extends EmptyInterceptor {

    @Override
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("Entity deleted: " + entity);
        super.onDelete(entity, id, state, propertyNames, types);
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
        System.out.println("Entity updated: " + entity);
        return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
    }

    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("Entity loaded: " + entity);
        return super.onLoad(entity, id, state, propertyNames, types);
    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("Entity saved: " + entity);
        return super.onSave(entity, id, state, propertyNames, types);
    }

    @Override
    public void postFlush(Iterator entities) {
        System.out.println("Post flush");
        super.postFlush(entities);
    }

    @Override
    public void preFlush(Iterator entities) {
        System.out.println("Pre flush");
        super.preFlush(entities);
    }
}

步骤二:配置Hibernate以使用拦截器

在创建SessionFactory实例时,我们需要将自定义的拦截器传递给Hibernate。

Hibernate配置文件 hibernate.cfg.xml
xml 复制代码
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
        <property name="hibernate.connection.username">your_username</property>
        <property name="hibernate.connection.password">your_password</property>

        <!-- Hibernate 属性配置 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 映射类 -->
        <mapping class="com.example.domain.Product"/>
    </session-factory>
</hibernate-configuration>
HibernateUtil类

HibernateUtil类中,我们将自定义的拦截器传递给Configuration对象。

java 复制代码
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.example.interceptor.CustomInterceptor;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
            configuration.setInterceptor(new CustomInterceptor());  // 设置自定义拦截器
            sessionFactory = configuration.buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

步骤三:使用Hibernate进行数据库操作

我们将创建一个包含一些CRUD操作的示例,以触发拦截器的各种方法。

示例操作类
java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.example.domain.Product;

public class HibernateInterceptorExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 插入示例数据
        insertSampleData(sessionFactory);

        // 更新示例数据
        updateSampleData(sessionFactory);

        // 查询示例数据
        querySampleData(sessionFactory);

        // 删除示例数据
        deleteSampleData(sessionFactory);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void insertSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Product product1 = new Product("Laptop", 1000.0);
            Product product2 = new Product("Smartphone", 500.0);
            session.save(product1);
            session.save(product2);
            transaction.commit();
            System.out.println("Inserted sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    private static void updateSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Product product = session.get(Product.class, 1L);
            product.setPrice(1200.0);
            session.update(product);
            transaction.commit();
            System.out.println("Updated sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    private static void querySampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        try {
            Product product = session.get(Product.class, 1L);
            System.out.println("Queried product: " + product.getName() + ", " + product.getPrice());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    private static void deleteSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Product product = session.get(Product.class, 1L);
            session.delete(product);
            transaction.commit();
            System.out.println("Deleted sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

详细解释

  1. 创建拦截器类

    • CustomInterceptor 类实现了 EmptyInterceptor
    • 重写了 onDelete, onFlushDirty, onLoad, onSave, preFlush, postFlush 等方法来插入自定义逻辑,比如打印日志。
  2. 配置Hibernate以使用拦截器

    • HibernateUtil 类中,使用 ConfigurationsetInterceptor 方法来设置自定义的拦截器。
    • 拦截器将在 SessionFactory 创建时被应用。
  3. 示例操作类

    • 包含了一些CRUD操作,用于演示如何在操作过程中触发拦截器的方法。
    • 通过 insertSampleData, updateSampleData, querySampleData, deleteSampleData 方法展示了数据的插入、更新、查询和删除操作。

通过这种方式,Hibernate中的拦截器可以在实体对象的生命周期事件发生时执行自定义的逻辑,从而实现类似日志记录、数据验证、审计等功能。

相关推荐
Victor3562 小时前
Hibernate(40)Hibernate的命名策略是什么?
后端
Knight_AL3 小时前
Spring 事务管理:为什么内部方法调用事务不生效以及如何解决
java·后端·spring
bcbnb3 小时前
iOS代码混淆技术深度实践:从基础到高级全面解析
后端
加洛斯3 小时前
SpringSecurity入门篇(2):替换登录页与config配置
前端·后端
用户8356290780513 小时前
Python 实现 Excel 条件格式自动化
后端·python
源代码•宸3 小时前
Golang语法进阶(协程池、反射)
开发语言·经验分享·后端·算法·golang·反射·协程池
Chan164 小时前
场景题:CPU 100% 问题怎么排查?
java·数据库·redis·后端·spring
我是谁的程序员4 小时前
iOS 文件管理,在不越狱的前提下管理 iPhone / iPad 文件
后端
v***59834 小时前
springBoot连接远程Redis连接失败(已解决)
spring boot·redis·后端