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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/901537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:50:44  来源:igfitidea点击:

Elegant ways to handle database views on hibernate entities?

javadatabasehibernate

提问by Roland Ewald

One of the main reasons I use Hibernate is that it provides the flexibility to switch to another database without having to rewrite any code.

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

But until now I did not figure out a good way to define additional views on the tables to which my hibernate entities are matched; I am still using simple SQL scripts for that. Is there a more elegant way to define views on tables managed by hibernate?

但直到现在,我还没有找到在与我的休眠实体匹配的表上定义附加视图的好方法;为此,我仍在使用简单的 SQL 脚本。有没有更优雅的方法来定义由 hibernate 管理的表的视图?

Ideally I would like to use HQL or another generic method to do the job, so that I don't have to worry about my SQL scripts being incompatible with other kinds of databases.

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

If there's a way to do that, a second issue would then be to get 'synthetic' read-only instances from these views, which should make it much easier to feed the aggregated data into a UI.

如果有办法做到这一点,那么第二个问题就是从这些视图中获取“合成”只读实例,这应该可以更轻松地将聚合数据提供给 UI。

EDIT:

编辑:

It seems as if I didn't make the problem clear enough, so here's what i am trying to do: I want to write code that is independent of the used database. Since I use hibernate, I would just have to change the dialect configuration file and could then use another DBMS.

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

Question: how to create viewson my hibernate entities withoutrelying on a specific SQL dialect (to keep everything portable), or even HQL? And if that's possible, can I use HQL to also query these views, i.e. to create read-only aggregate entities? Is there any additional hibernate plug-in to help me with that? Haven't found anything so far... :-/

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

采纳答案by Rob H

Hibernate will not automatically create the views for you, as each dialect supports only a limited subset of the data-definition language (DDL) of the underlying database. Basically, it supports enough DDL to generate a working schema, but not enough to handle creation of "extra" objects like views.

Hibernate 不会自动为您创建视图,因为每种方言仅支持底层数据库的数据定义语言 (DDL) 的有限子集。基本上,它支持足够的 DDL 来生成工作模式,但不足以处理“额外”对象(如视图)的创建。

All is not lost, though. Hibernate does give you the ability to create (and drop) additional database objects yourself in the XML mapping files, and those objects can be scoped to a particular dialect. For example, I could have a mapping like this:

然而,一切都没有丢失。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>

You're free to create whatever additional views you want by adding more "database-object" sections. You have to write the SQL (DDL) yourself for each database you want to support, but since they're scoped to the dialect, Hibernate will only execute the SQL for the dialect chosen at schema export time.

通过添加更多“数据库对象”部分,您可以自由地创建您想要的任何其他视图。您必须为您想要支持的每个数据库自己编写 SQL (DDL),但由于它们的范围仅限于方言,Hibernate 将只为模式导出时选择的方言执行 SQL。

回答by Ben Hammond

Can you declare the views directly inside the database? Then you can just select directly from the views. Have a look at chapter 10.4.4 of the Hibernate manual

你能直接在数据库中声明视图吗?然后您可以直接从视图中进行选择。看看Hibernate 手册的第 10.4.4 章

That should allow you to SELECT from the database view and get Hibernate to automatically hydrate the data into your entities.

这应该允许您从数据库视图中进行 SELECT 并让 Hibernate 自动将数据混合到您的实体中。

Of course, a view doesn't take any parameters. Hibernate 3 is supposed to support stored procedures, but I've used that.

当然,视图不带任何参数。Hibernate 3 应该支持存储过程,但我已经使用了它。

回答by Tom

What do you mean by "create view"? I know what it means from a pure DB context - but that is not what you mean - right?

“创建视图”是什么意思?我从纯数据库上下文中知道这意味着什么 - 但这不是你的意思 - 对吧?

You can either map new Java classes to the same tables to create a "view" or you can use HQL to select a subset of the columns mapped by other persistent classes.

您可以将新的 Java 类映射到相同的表以创建“视图”,也可以使用 HQL 选择由其他持久类映射的列的子集。

HTH

HTH

回答by Dominik

Had the same problem and found the following solution in the hibernate doucmentation:

遇到了同样的问题,在 hibernate 文档中找到了以下解决方案:

There is no difference between a view and a base table for a Hibernate mapping. This is transparent at the database level, although some DBMS do not support views properly, especially with updates. Sometimes you want to use a view, but you cannot create one in the database (i.e. with a legacy schema). In this case, you can map an immutable and read-only entity to a given SQL subselect expression:

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

https://docs.jboss.org/hibernate/stable/core/manual/en-US/html_single/#mapping-declaration