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

3

我希望能拦截数据库中的插入查询,并更改其插入值。

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

总体上我想拦截JDBC连接中执行的查询。


2
我认为你可以在这里使用AOP。 - Gaurav Jeswani
2
https://dev59.com/-6nka4cB1Zd3GeqPOHHM - Akash Shah
3
你可以使用一个触发器。 - Maurice Perry
2
如果您想拦截所有JDBC的数据库操作,可以尝试使用p6spy来自定义此功能。 - LHCHIN
1
你对赏金有什么期望?建议的触发器解决方案怎么样?如果你想要特定的触发器,请在表格上提供更多细节。 - user7294900
显示剩余5条评论
2个回答

3

在数据库中使用触发器实现

我认为实现这个功能的最佳方式是直接在数据库中使用触发器。那正是它们被设计出来的目的。它们将保证每个试图插入/更新/合并user.name值的客户端都会经过这个逻辑。不会出现某些其他开发人员聪明地编写Perl脚本,不知道你的客户端拦截。

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

在客户端中使用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语句等)。触发器是解决这个问题的最佳途径。


1

如Mureinik所建议,使用插入时触发器

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接