【问题标题】:Hibernate and stored procedures休眠和存储过程
【发布时间】:2011-01-25 00:20:07
【问题描述】:
根据我对设置休眠的理解,我需要创建
- 表元数据文件(
person.hbm.xml),包含所有字段映射
- java 对象 (
person.java)
如果我们对所有事务都使用存储过程,还需要上面的配置吗?
看来hibernate和存储过程会重叠,
我们设置存储过程是因为我们不希望开发人员知道数据库中的所有字段。如果表发生变化,那么我们需要更新上面的文件。
是否意味着如果我们纯粹使用存储过程,我们应该只使用 JDBC?
如果休眠,我们应该留在HQL吗?
【问题讨论】:
标签:
java
oracle
hibernate
stored-procedures
orm
【解决方案1】:
您可以使用原生 SQL 并将结果映射到对象:
sess.createSQLQuery("SELECT * FROM CATS").addEntity(Cat.class);
调用存储过程的JDBC语法如下:
CallableStatement proc =
connection.prepareCall("{ call set_death_age(?, ?) }");
proc.setString(1, poetName);
proc.setInt(2, age);
所以也许,你可以调用存储过程并将它们映射到对象:
sess.createSQLQuery("{ call my_stored_proc }").addEntity(Cat.class);
另请注意,通过存储过程进行的更新 将退出休眠状态,这意味着您需要自己从第一级和第二级缓存 中逐出对象。
如您所见,hibernate 和存储过程并不是很自然地结合在一起。
我们设置存储过程是因为
我们不希望开发人员知道
db 中的所有字段。如果表改变,
那么我们需要更新上面的文件。
如果您担心安全性,请使用:
【解决方案2】:
将 Hibenate 与存储过程一起使用存在一定的重叠。例如,当您需要为 INSERT、UPDATE、DELETE 和 SELECT 编写存储过程时,Hibernate 通过将关系数据库对象映射到您提到的 person.hbm.xml 等元数据文件中,提供了一种与关系数据库对象交互的最简单方法。
是的,存储过程的使用无论如何都需要您编写这些元数据文件。存储过程不会替换 Hibernate 映射。这些映射只告诉 Hibernate 如何将你的面向对象模型持久化到数据库中。 Hibernate 的一大优点是,如果需要,您甚至可以通过模式生成工具从 JAVA 代码生成数据库模型。
对于存储过程,一种推荐的方法是将存储过程配置为配置文件中的命名查询。然而,在我看来,这会让你错过 Hibernate 的更好潜力。
这是否回答了您的问题?您需要进一步解释吗?
【解决方案3】:
可以使用native-sql 和stored procedure for querying(和limiations/rules)。但是,正如文档中所写:
存储过程目前只返回标量和实体。不支持<return-join> 和<load-collection>。
因此,如果您想使用非托管实体(即不是 Object[] 中的标量),则必须在代码中应用 ResultTransformer。
但最后,如果您想对开发人员隐藏数据库,如果您不想将对象映射到表,如果您不想使用关联,如果您不想使用 HQL ,如果您不想使用 OO 方法,那么我真的想知道您为什么要使用 Hibernate。你最好使用原始 JDBC(例如 Spring)或者像 iBATIS 这样的数据映射器。
【解决方案4】:
您可以将结果集中的数据库字段映射到休眠中的对象:the documentation 解释了如何。
Hibernate 的想法是填补对象-关系的空白。使用存储过程(我无法猜测,因为您没有告诉过它们),您无法从数据库中获取对象。你仍然会得到行。
对我来说,向开发人员隐藏数据库列听起来是一种不好的做法。将它们从应用程序中隐藏也许是您想要的,您可以通过元数据文件来实现。