如何拦截Hibernate生成的SQL?

6
对于一个作为大兄弟的安全系统(类似于被监视的强制访问控制),我们必须拦截并处理Hibernate生成的所有select语句。 我们将用户、时间戳和SQL select存储在数据库中,以便使用其他工具进行一些分析。 这些信息可以确定用户试图查看什么。 对于select语句,准备好的属性很有价值。 我们需要完整的SQL语句,包括所有参数。
是否有任何监听器或拦截器可以加入并处理所有这些内容?到目前为止最大的问题是收集语句参数。
谢谢

mkyong声称p6spy.jar可以显示带参数值的Hibernate查询。也许你可以尝试这个http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/。 - Naveen
2个回答

3
您可以使用Interceptor.prepareSQL()(3.1+)拦截预处理语句。
我认为您无法在不降低抽象层的情况下获取实际参数。一个可能的解决方案是使用JDBC代理驱动程序(请参见P6Spy)。
希望这能帮到您。

是的,了解这个接口后,如何获取绑定参数呢?据我所知,没有办法获取实际参数。 - Christopher Klewes
准确来说,它是 Interceptor#onPrepareStatement(String sql)。但这只能让你访问被准备的 SQL 字符串,而不是生成的查询。 - Pascal Thivent

3
实际参数值(据我所知)在将org.hibernate包的日志级别设置为DEBUG并设置{{hibernate.show_sql}}属性时可用。如果想要将记录器输出放在数据库中,请使用JDBCAppender。或者,您可以查看log4jdbc项目,该项目声称:在记录的输出中,对于准备好的语句,绑定参数会自动插入到SQL输出中。这极大地提高了许多情况下的可读性和调试能力。
如果这不合适的话,您可以调查一下是否可以在您的情况下使用P6Spy。在WebLogic Server上,通过WebLogic JDBC Spy实现等效功能,它与某些数据库的WebLogic JDBC驱动程序一起提供。这两者都写入System.out而不是数据库(除非我弄错了),因此可能没有太大用处。

这个很有效,我编写了自己的 appender 将语句写入数据库。唯一困扰我的问题是如何获取触发此语句的相应用户。这几乎是不可能解决的。有任何想法吗? - Christopher Klewes
1
我不确定这个,因为我没有试过。基本上,您需要将执行SQL语句的用户/主体映射到被记录的数据上。在SLF4J/log4j/logback中,通过MDC - Mapped Diagnostic Context实现这一点。您的模式字符串还需要修改以容纳主体。有关在logback中使MDC工作的文章可能会有所帮助- http://logback.qos.ch/manual/mdc.html 顺便说一句,如果可以修改附加程序模式字符串以反映用户(如果这是缺少格式字符串的情况),则不需要MDC。 - Vineet Reynolds
非常感谢,我选择了log4jdbc项目,因为它是最活跃的一个,这个选择非常好。再次感谢。 - Christopher Klewes

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