如何从Hibernate saveOrUpdate(Object)获取查询(不用于记录)

时间:2015-02-11 09:27:41

标签: java hibernate

在Hibernate中有一项规定,您可以从Criteria How to get SQL from Hibernate Criteria API (*not* for logging)获取查询,但我希望从Hibernate saveOrUpdatedelete(Object)获取更新/删除查询,那么有没有选项?

3 个答案:

答案 0 :(得分:1)

我所知道的没有这样的选择。更新/保存(插入)/删除方法是懒散发布的。在十年前的早期,这是考虑Hibernate的主要特征之一。

只有当select选中数据库,发出flush或发生提交时,Hibernate才会发出更新/保存/删除操作。然后Hibernate遍历所有对象(及其图形)以检查脏对象。出于脏点,它生成必要的SQL并尝试创建批量的更改。这样可以节省连接时间并一次传输许多更改。如果您必须删除/插入/更新同一个表中的大量行,它可以大大加快数据库访问速度。

但这使得无法从这样的动作接收Hibernate生成的SQL,因为动作不存在但它只是POJO对象中的标记。


如果你想要SQL,你可以做两件事。首先,您可以替换Driver实现并向其中插入任何类型的日志记录(就像监视工具一样)。只需获取当前Driver实现的源代码,并在自己的类路径中创建一个类+包,并修改execute + setParameter等方法。通过这种方式,您可以查看并以编程方式获取SQL命中数据库的内容,还可以替换结果集实现并检查代码下次发出的频率以及各种各样的内容。

我用它进行单元测试,效果很好。

-

第二种方法更容易。您只需进入Hibernate的源代码并亲自查看即可。如果Garvin(King)有一个特殊的特性,那么它就是编写好的可读代码。只有极少数情况下你可以和他争论他的写作方式(对我而言,这些方法有点太长了)但除了这个非常好的阅读之外。因此,如果您能够掌握Hibernates源代码(这很容易),那么值得一读。我消耗了一周的源代码,我猜Hibernate 3,这很有意思(Eclipse也很好读)。

检查代码后,您将看到在编写SQL之前存在表示SQL的类,并且有Dialect对象和所有内容。调查它们,复制源根据原始版本提供您自己的实现,然后您可以再次监视存储和访问,甚至操纵导致最终SQL的所有事情,甚至在将其移交给数据库驱动程序之前获取SQL。

-

第一个选项适合查看所有SQL。第二种选择非常适合获得对Hibernate的感觉,并增加对实际操作的控制。

答案 1 :(得分:0)

正如您所提到的,可以从Criteria,QueryDSL或命名查询(例如,使用QueryTranslator)获取生成的SQL查询运行时,但遗憾的是,对于已构建的内容,这是不可能的。 -in方法如save(),update()等

获取(to see,更确切地说)生成SQL的唯一方法是通过日志记录或数据库监视工具。

虽然这是最需要的功能之一,但到目前为止它不是规范的一部分,所以它严格依赖于供应商的实现(和愿望)。也就是说,至少在这个时刻,Hibernate没有提供任何方法来实现这一目标。

答案 2 :(得分:0)

如果要自定义UPDATE / DELETE语句,只需提供your own CRUD DML语句:

@Entity
@Table(name="CHAOS")
@SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)") 
@SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?") 
@SQLDelete( sql="DELETE CHAOS WHERE id = ?") @SQLDeleteAll( sql="DELETE CHAOS")