拦截 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;
我想在我的数据库中拦截插入查询并想更改它的插入值
例如,如果用户在数据库中插入一个值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;