stack overflow上面几篇文章:
1、http://stackoverflow.com/questions/5847427/hibernate-from-view
2、http://stackoverflow.com/questions/5111176/view-with-hibernate
3、http://stackoverflow.com/questions/15215757/creating-views-through-hibernate
4、http://stackoverflow.com/questions/901537/elegant-ways-to-handle-database-views-on-hibernate-entities
总结:
1、用hibernate创建视图只能用sql:
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.
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-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.
2、或者不创建,只是在hibernate中使用子查询
Had the same problem and found the following solution in the hibernate doucmentation:
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:
<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
注解的方法:
you can use a @subselect annotation
here are an example of official documentation:
@Entity
@Subselect("select item.name, max(bid.amount), count(*) "
+ "from item "
+ "join bid on bid.item_id = item.id "
+ "group by item.name")
@Synchronize( {"item", "bid"} ) //tables impacted
public class Summary {
@Id
public String getId() { return id; }
...
}
或者:
Subselect is your natural choice.Here is a working example: Say we have a view named "view1" in the DBMS. You don't need anything else, althought if the view is not updatable, using @Immutable would be nice for performance issues. Notice that you must have an id column in your class and in the view
@Entity
@Subselect("select * from view1")
public class EventView {
@Id @GeneratedValue
private int id;
3、
Don't create your entity of the view the wrong way.If you use @SqlResultSetMapping and @NamedNativeQuery to create a view, your code will work fine and use the view correctly but hibernate auto ddl feature will create an unused table for your entity.You can see the most straight way to create a view
here
4、
Another option is to put the view creation sql in a script that is run by hbm2ddl by configuring property
hibernate.hbm2ddl.import_files
Assuming that you have an entity that represents that view, you must do a drop table before creating the view, since hbm2ddl will create a table if it doesn't find an existing view by that name.