拦截 Java 中的所有数据库调用

Intercept all Database call in Java

我想在我的数据库中拦截插入查询并想更改它的插入值

例如,如果用户在数据库中插入一个值name = amitrai,我想将值从amitrai &^&WQWSAKJSJA然后存储.

总体而言,我希望拦截在 JDBC 连接中执行查询。

在数据库中使用触发器进行。

在我看来,最好的实现方法是直接在数据库中使用触发器。这正是它们的用途。他们将保证每个尝试插入/更新/合并 user.name 值的客户端都将通过此逻辑。其他一些不知道您的客户端拦截的开发人员不会有聪明的 Perl 脚本。

您在评论中提到的所有数据库产品都支持触发器。当然,缺点是你必须在你想要支持的方言中重复你的编码/哈希逻辑。

在客户端执行,使用 JDBC 代理

如果您出于某种原因必须在客户端中实现此逻辑,那么 JDBC 是执行此操作的好层。当然,您可以在更高层(例如在 Hibernate 中)实现它,但话又说回来,您将冒一些 Java 客户端逻辑绕过此编码的风险。

在JDBC层,你至少可以"reasonably"保证每个Java客户端都会执行这个逻辑。

解决这个问题的一种方法是使用 jOOQ 的各种连接代理,包括 MockConnection, which allows for intercepting most JDBC calls using a single method (with some limitations), the ParsingConnection, which allows for parsing the SQL string that is being passed to JDBC, and then transform. If you want to produce new SQL logic, you'd be using the VisitListener 将 SQL 转换为其他东西。在你的例子中,你只是替换了一个绑定变量,所以你可以更容易地做到这一点。

免责声明:我在 jOOQ 背后的公司工作。可能还有其他支持类似行为的解决方案,其本质是代理(其他人为此提到了 p6spy)和解析,以确保您只替换您实际想要替换的值。像 jOOQ 一样,这样的解决方案不应该强迫您在客户端逻辑中实际 使用 jOOQ,而是拦截您在 JDBC 上执行的任何类型的 SQL图层。

注意事项

虽然上述在某种程度上是可行的,但它可能很复杂,并且您可能仍然忽略了一些事情(例如 MERGE 语句或 INSERT .. ON DUPLICATE KEY UPDATE 语句等。 ).触发器是解决此问题的最佳方法。

按照@Mureinik 的建议使用Trigger on insert

例如 table yourtable 插入:

CREATE OR REPLACE TRIGGER NameChange
    BEFORE INSERT
    ON yourtable
    FOR EACH ROW
BEGIN
    IF :new.name = 'amitrai'
    THEN
        :new.name := '&^&WQWSAKJSJA';
    END IF;
END;