我希望能拦截数据库中的插入查询,并更改其插入值。
例如,如果用户在数据库中插入一个值 name = amitrai,我想将该值从 amitrai 更改为 &^&WQWSAKJSJA 并存储。
总体上我想拦截JDBC连接中执行的查询。
我希望能拦截数据库中的插入查询,并更改其插入值。
例如,如果用户在数据库中插入一个值 name = amitrai,我想将该值从 amitrai 更改为 &^&WQWSAKJSJA 并存储。
总体上我想拦截JDBC连接中执行的查询。
我认为实现这个功能的最佳方式是直接在数据库中使用触发器。那正是它们被设计出来的目的。它们将保证每个试图插入/更新/合并user.name
值的客户端都会经过这个逻辑。不会出现某些其他开发人员聪明地编写Perl脚本,不知道你的客户端拦截。
你在评论中提到的所有数据库产品都支持触发器。缺点是,当然,你必须在想要支持的所有方言中重复编码/哈希逻辑。
如果由于某种原因必须在客户端中实现此逻辑,则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
语句等)。触发器是解决这个问题的最佳途径。
如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;