我使用Hibernate的一个主要原因是它提供了切换到另一个数据库的灵活性,而无需重写任何代码。
但到目前为止,我还没有想出一个在我的hibernate实体匹配的表上定义其他视图的好方法;我仍在使用简单的SQL脚本。有没有更优雅的方法来定义由hibernate管理的表的视图?
理想情况下,我想使用HQL或其他通用方法来完成这项工作,这样我就不必担心我的SQL脚本与其他类型的数据库不兼容。
如果有办法解决这个问题,那么第二个问题就是从这些视图中获取“合成”只读实例,这样可以更容易地将聚合数据提供给用户界面。
修改
好像我没有把问题弄清楚,所以这就是我想要做的:我想编写独立于使用过的数据库的代码。由于我使用hibernate,我只需要更改方言配置文件,然后可以使用另一个DBMS。
问题:如何在我的hibernate实体上创建视图,而依赖于特定的SQL方言(以保持一切可移植性),甚至是HQL?如果可能的话,我可以使用HQL查询这些视图,即创建只读聚合实体吗?是否有任何额外的hibernate插件来帮助我?到目前为止还没找到任何东西......: - /
答案 0 :(得分:22)
Hibernate不会自动为您创建视图,因为每个方言仅支持底层数据库的数据定义语言(DDL)的有限子集。基本上,它支持足够的DDL来生成工作模式,但不足以处理视图等“额外”对象的创建。
但是,一切都不会丢失。 Hibernate确实使您能够在XML映射文件中自己创建(和删除)其他数据库对象,并且这些对象可以作用于特定方言。例如,我可以有这样的映射:<hibernate-mapping>
<class name='com.mycompany.myproduct.Customer' table='tbl_customer'>
<id name='id' column='customer_id'>
<generator class='native'/>
</id>
<property name='name' length='50' unique='true' not-null='true' />
</class>
<database-object>
<create>create or replace view read_only_cust...</create>
<drop>drop view read_only_cust</drop>
<dialect-scope name='org.hibernate.dialect.Oracle9Dialect' />
</database-object>
</hibernate-mapping>
您可以通过添加更多“数据库对象”部分来自由创建所需的任何其他视图。您必须自己为要支持的每个数据库编写SQL(DDL),但由于它们的范围是方言,因此Hibernate只会为在模式导出时选择的方言执行SQL。
答案 1 :(得分:12)
遇到同样的问题,在hibernate doucmentation中找到了以下解决方案:
视图之间没有区别 和一个Hibernate的基表 映射。这是透明的 数据库级别,虽然有些DBMS可以 特别是不能正确支持观点 有更新。有时你想 使用视图,但不能创建一个 在数据库中(即具有遗产 模式)。在这种情况下,您可以映射一个 不可变和只读实体到 给定SQL子选择表达式:
<class name="Summary">
<subselect>
select item.name, max(bid.amount), count(*)
from item
join bid on bid.item_id = item.id
group by item.name
</subselect>
<synchronize table="item"/>
<synchronize table="bid"/>
<id name="name"/>
...
</class>
https://docs.jboss.org/hibernate/stable/core/manual/en-US/html_single/#mapping-declaration
答案 2 :(得分:0)
您可以直接在数据库中声明视图吗? 然后您可以直接从视图中选择。 看看chapter 10.4.4 of the Hibernate manual
这应该允许您从数据库视图中选择并让Hibernate自动将数据水合成您的实体。
当然,视图不带任何参数。 Hibernate 3应该支持存储过程,但我已经使用过了。
答案 3 :(得分:0)
“创建视图”是什么意思?我知道纯数据库环境意味着什么 - 但这不是你的意思 - 对吧?
您可以将新Java类映射到相同的表以创建“视图”,也可以使用HQL选择由其他持久类映射的列的子集。
HTH