【问题标题】:Intercept all Database call in Java拦截 Java 中的所有数据库调用
【发布时间】:2019-11-19 06:18:49
【问题描述】:

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

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

总的来说,我希望拦截在 JDBC 连接中执行查询。

【问题讨论】:

  • 请尽量不用hibernate和spring回答
  • 我觉得你可以在这里使用AOP。
  • 你可以使用触发器
  • 如果你想拦截JDBC的所有DB操作,可以试试p6spy自定义这个功能。

标签: java database connection


【解决方案1】:

在数据库中使用触发器。

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

您在 cmets 中提到的所有数据库产品都支持触发器。当然,缺点是您必须在尽可能多的方言中重复您的编码/散列逻辑。

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

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

在 JDBC 层,你至少可以“合理地”保证每个 Java 客户端都会执行这个逻辑。

解决这个问题的一种方法是使用类似 jOOQ 的各种连接代理,包括 MockConnection,它允许使用单一方法(有一些限制)拦截大多数 JDBC 调用,ParsingConnection,它允许解析传递给 JDBC 的 SQL 字符串,然后进行转换。如果您想生成新的 SQL 逻辑,您将使用 VisitListener 将 SQL 转换为其他内容。在你的情况下,你只是替换一个绑定变量,所以你可以更容易地做到这一点。

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

注意事项

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

【讨论】:

    【解决方案2】:

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

    例如对于表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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 2019-10-05
      • 2018-06-08
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多