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中的拦截器可以在实体对象的生命周期事件发生时执行自定义的逻辑,从而实现类似日志记录、数据验证、审计等功能。

相关推荐
William_cl3 分钟前
ASP.NET路由长度约束精讲:[HttpGet (“{name:minlength (3)}“)] 字符长度限制吃透,附避坑指南 + 实战代码
后端·asp.net
我命由我1234512 分钟前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
szhf7812 分钟前
SpringBoot Test详解
spring boot·后端·log4j
无尽的沉默13 分钟前
SpringBoot整合Redis
spring boot·redis·后端
摸鱼的春哥19 分钟前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
Victor35636 分钟前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack37 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo37 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor35638 分钟前
MongoDB(3)什么是文档(Document)?
后端
牛奔3 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang