当前位置: 首页 > 知识库问答 >
问题:

Spring Boot HiberNate Web应用程序:如何全局拦截本机和托管实体查询?

潘坚白
2023-03-14

是否可以在数据库连接或数据源的底层放置一个钩子,并在执行任何其他查询之前执行一个查询?

你好。

我希望能够在Hibernate状态下拦截所有数据库查询,并在原始查询发送到数据库之前注入执行一个简单的查询:SET @SomeSessionVariable = 123346;

由于hibernate对其管理的实体使用生命周期,所以我发现实现我所需要的是一个挑战。

在我的Spring启动应用程序中,我想使用触发器审核数据更改。我希望能够将更改与Spring应用程序中当前登录的用户相关联,唯一的方法是将该用户的id连同任何查询一起发送到数据库,但就在查询执行之前,以便触发器可以在当前连接会话中看到变量。

我用的是MySQL,似乎没有内置的方式来做到这一点。Postgresql似乎确实支持向DBMS发送客户机上下文。

应用程序非常庞大,需要重构以手动发送id。

你知道我可以在Hibernate配置中放置全局钩子以能够拦截本机和托管查询的任何其他位置吗?

共有1个答案

章侯林
2023-03-14

如果您在应用程序中使用 spring-security 来验证用户身份,则可以根据需要使用 spring-data-jpa 审核系统。

例如,对于< code>Product实体,它可能如下所示:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Product {
    
    // id and other fields
    
    @Column(name = "created_by")
    @CreatedBy
    private String createdBy;

    @Column(name = "modified_by")
    @LastModifiedBy
    private String modifiedBy;
    
    // getters, setters, etc.
}

您还应该在任何配置类上放置< code>@EnableJpaAuditing注释。

通过这样做,您将告诉 spring-data 在保存或更新操作时自动将created_bymodified_by字段插入数据库关系中,使用存储在 SecurityContext身份验证对象中的主体的名称以及调用保存或更新的人员。

您可以通过实现审核员感知来更改此默认行为

public class CustomAuditorAware implements AuditorAware<String> {
    @Override
    public Optional<String> getCurrentAuditor() {
        // retrieve name, id or anything else from your SecurityContext
    }
}

然后,您只需将此< code>AuditorAware注册为bean,并将您的应用程序指向它:

@EnableJpaAuditing(auditorAwareRef = "auditor")
@Configuration
public class ApplicationConfig {
    @Bean
    AuditorAware<String> auditor() {
        return new CustomAuditorAware();
    }
}

请注意,此审核机制仅适用于实体,因此不适用于本机查询。还有其他方法可以实现实体审计 - 看看Baeldung的这篇文章

如果您想在执行原生sql查询之前修改它们,可以使用Hibernate的< code>StatementInspector:

public class CustomStatementInspector implements StatementInspector {
    @Override
    public String inspect(String sql) {
        // check if query is modifying and change sql query 
    }
}

然后,您应该让Spring知道您想使用此检查器,并且在Spring Boot中有一种简单的方法可以做到这一点:

@Configuration
public class ApplicationConfig {
    @Bean
    public HibernatePropertiesCustomizer hibernateCustomizer() {
        return (properties) -> properties.put(AvailableSettings.STATEMENT_INSPECTOR, new CustomStatementInspector());
    }
}

其他配置<code>StatementInspector</code>的方法可以在这里找到:如何在Hibernate中配置StatementInspection?

 类似资料:
  • 如何获取从驱动程序发送到的确切查询(出于调试目的)。 在mysql中,通过将添加到DataSource来实现。 我正在编写一个聚合查询,在开始日期和结束日期之间有一个匹配的管道。日期是以普通java日期类的形式给出的。 而且它似乎没有根据日期过滤结果。它把一切都还给我。

  • 是否可以在Spring Boot中集成Spring托管Hibernate拦截器(http://docs.jboss.org/Hibernate/orm/4.3/manual/en-us/html/ch14.html)? 我正在使用Spring Data JPA和Spring Data REST并需要一个Hibernate拦截器来处理实体上特定字段的更新。 对于标准的JPA事件,不可能获得旧值,因此

  • 问题内容: 如何在CLI(命令行界面)Java应用程序中截获 (通常会杀死进程)? 是否存在多平台解决方案(Linux,Solaris,Windows)? 我使用的是,但是如有必要,我可以使用其他方法从标准输入中读取字符。 问题答案: 这应该能够截获信号,但是仅作为JVM完全关闭自身之前的中间步骤,因此它可能不是你要注意的。 你需要使用截获 触发的信号C(在Unix和Windows上)。

  • 所以我有一个Web应用程序,其中前端是用React编写的,后端是用NodeJs/NestJ编写的,并且处于部署应用程序的阶段。我有一个运行Ubuntu的Linode服务器,我最初的想法是安装Docker 那么,这是设置应用程序的好方法吗?这种设置有什么利弊吗?除了因为需要服务器数量而定价之外?或者还有其他更有益的选择吗? 提前致谢。

  • 我想在我的Quarkus应用程序中添加一个HTTP拦截器,这样我就可以拦截所有HTTP请求。如何实现?

  • 我使用这个配置将全局css配置应用到基于JavaScript的React项目中: css文件: 阿普泰克斯 但是没有应用例如字体样式。你知道基于TypeScript的React项目合适的配置是什么吗?