簡體   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