在hibernate实体上处理数据库视图的优雅方法?

时间:2009-05-23 13:28:16

标签: java database hibernate

我使用Hibernate的一个主要原因是它提供了切换到另一个数据库的灵活性,而无需重写任何代码。

但到目前为止,我还没有想出一个在我的hibernate实体匹配的表上定义其他视图的好方法;我仍在使用简单的SQL脚本。有没有更优雅的方法来定义由hibernate管理的表的视图?

理想情况下,我想使用HQL或其他通用方法来完成这项工作,这样我就不必担心我的SQL脚本与其他类型的数据库不兼容。

如果有办法解决这个问题,那么第二个问题就是从这些视图中获取“合成”只读实例,这样可以更容易地将聚合数据提供给用户界面。

修改

好像我没有把问题弄清楚,所以这就是我想要做的:我想编写独立于使用过的数据库的代码。由于我使用hibernate,我只需要更改方言配置文件,然后可以使用另一个DBMS。

问题:如何在我的hibernate实体上创建视图,而依赖于特定的SQL方言(以保持一切可移植性),甚至是HQL?如果可能的话,我可以使用HQL查询这些视图,即创建只读聚合实体吗?是否有任何额外的hibernate插件来帮助我?到目前为止还没找到任何东西......: - /

4 个答案:

答案 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