繁体   English   中英

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

[英]Spring Boot + Hibernate Web Application: How to globally intercept native and managed entity queries?

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

你好。

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

由于 hibernate 对其托管实体使用生命周期,因此我发现实现我需要的东西是一个挑战。

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

我正在使用 MySQL 似乎没有内置的方法可以做到这一点。 Postgresql 似乎确实支持将客户端上下文发送到 DBMS。

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

您知道我可以在 hibernate 配置中放置一个全局挂钩以拦截本机和托管查询的其他地方吗?

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

例如,对于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.
}

此外,您应该将@EnableJpaAuditing注释放在任何配置类上。

通过这样做,您将告诉 spring-data 在保存或更新操作时使用存储在SecurityContextAuthentication object 中的主体名称以及调用保存或更新的主体名称自动将created_bymodified_by字段插入到数据库关系中。

您可以通过实现AuditorAware<T>接口来更改此默认行为

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

然后你只需要将这个AuditorAware注册为一个 bean 并将你的应用程序指向它:

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

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

如果你想在执行之前修改原生 sql 查询,你可以使用 Hibernate 的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());
    }
}

可以在此处找到其他配置StatementInspector的方法:如何在 Hibernate 中配置 StatementInspector?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM