如何在Hibernate中配置StatementInspector?

6jjcrrmo  于 2023-10-23  发布在  其他
关注(0)|答案(5)|浏览(239)

https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Interceptor.html表示onPrepareStatement(String sql)已弃用。如果您希望检查和更改SQL语句,请提供StatementInspector。
但我不清楚如何在应用程序级别上配置Hibernate中的StatementInspector(我不想在每个Hibernate会话级别上设置它)。

zour9fqk

zour9fqk1#

注册StatementInspector的最佳方法是使用hibernate.session_factory.statement_inspector配置属性。
这样,无论您是否使用JPA引导Hibernate(例如,Spring Data JPA)或原生Hibernate(例如SpringHibernateTranscationManagerLocalSessionFactoryBean)。
因此,您可以通过persistence.xml JPA配置文件提供hibernate.session_factory.statement_inspector

<property
    name="hibernate.session_factory.statement_inspector"
    value="com.vladmihalcea.book.hpjp.hibernate.logging.inspector.SqlCommentStatementInspector"
/>

或者,如果你使用Spring,你也可以编程地设置hibernate.session_factory.statement_inspector

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan({
        "com.vladmihalcea.books.high.performance.java.persistence"
    });
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager
      = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

private final Properties hibernateProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty(
      "hibernate.session_factory.statement_inspector", 
      SqlCommentStatementInspector.class
    );
    hibernateProperties.setProperty(
      "hibernate.dialect", 
      "org.hibernate.dialect.H2Dialect"
    );

    return hibernateProperties;
}

请注意,hibernate.session_factory.statement_inspector设置可以采用String(表示实现StatementInspector接口的完全限定类)、Class<? extends StatementInspector>StatementInspector对象引用。

s5a0g9ez

s5a0g9ez2#

不要这样做)
你只需要两样东西:
1.将属性添加到persistence.xml:
属性名=“hibernate.session_factory.statement_inspector”值=“全限定类名”
1.通过实现接口org. hibernate. resource. jdbc. spi. StatementInspector编写侦听器类。
利润!

snvhrwxg

snvhrwxg3#

可以在Spring中使用HibernatePropertiesCustomizer

@Configuration
public class HibernateConfig {

    @Bean
    public HibernatePropertiesCustomizer configureStatementInspector() {
        return (properties) -> properties.put(AvailableSettings.STATEMENT_INSPECTOR, (StatementInspector) sql -> {
            // figure out what to return
            return sql;
        });
    }
}
jtw3ybtb

jtw3ybtb4#

为了让这个工作,你必须引导Hibernate。要执行此操作,请执行以下操作:
在你的主类中,找到你的BidgetyManagerFactory示例。它可能看起来像这样:

public static final EntityManagerFactory EMPFAC = Persistence.createEntityManagerFactory("jpa")

先别排队。在其上增加以下内容:

private static StandardServiceRegistryBuilder servReg = new StandardServiceRegistryBuilder();
static {
    //Do this for every property in persistence.xml
    servReg.applySetting("hibernate.connection.url", "jdbc://myurl://www.example.org");
}

persistence.xml中的每个属性添加servReg.applySetting()。然后,在它下面添加这个:

private static MetadataSources sources = new MetadataSources(servReg.build());
static {
    // Do this for every pojo with JPA annotations
    sources.addAnnotatedClass(Pojo.class);
}

为应用程序中的每个带JPA注解的pojo添加sources.addAnnotatedClass()。快好了。现在创建一个实现StatementInspector的类,如下所示:

public class Inspector implements StatementInspector {

    private static final long serialVersionUID = 5545844969759630544L;

   @Override
   public String inspect(String select) {
       // modify string here
       return select;
   }
}

最后,回到你的主应用程序类,在你注册pojo的静态块下面,添加以下内容:

public static final SessionFactory EMPFAC = sources.buildMetadata().getSessionFactoryBuilder().applyStatementInspector(new Inspector()).build();

现在您可以返回到persistence.xml并删除那里的属性声明。如果还没有,请删除public static final EntityManager声明(已将其替换为SessionFactory)。
编辑:您实际上可以删除persistence.xml,您的应用程序仍然可以正常工作。
都准备好了

slsn1g29

slsn1g295#

事情没有太大的变化-基本上有些东西被重命名,所以从旧的“拦截器”代码的例子,你可以在网上找到,你只需要适应这些名称的变化。如果你手动构建SessionFactory(就像我一样),你可以这样做:

public class MyInspector implements StatementInspector {
   @Override
   public String inspect(String sql) {
       System.out.println(sql); // or whatever you want to do
       return sql;
   }
}

然后,在设置SessionFactory时,插入它的方式与之前插入Interceptor的方式非常相似

Configuration config = new Configuration();
config.setProperty("hibernate.connection.username", "myusername");
// ...
config.addAnnotatedClass(SomeClass.class);
// ...
config.setStatementInspector(new MyInspector()); // !!!!!!!!!!!!!!
SessionFactory mySessionFactory = config.buildSessionFactory();
// do something with the session factory

参见6.1中的setInterceptor与6.2中的setStatementInspector的比较

相关问题