[英]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 在保存或更新操作时使用存储在SecurityContext
的Authentication
object 中的主体名称以及调用保存或更新的主体名称自动将created_by
和modified_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.