`
software_developer
  • 浏览: 33969 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate学习笔记(2):Hibernate中子查询(subselect)的使用

阅读更多

 有些数据库不支持视图的创建,而实际业务中我们需要通过视图才能实现我们的需求,这时就可以使用Hibernate中子查询(subselect)

一,官方文档说明

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 using @org.hibernate.annotations.Subselect:

@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; }
    ...
}

 

定义这个实体用到的表为同步(synchronize),确保自动刷新(auto-flush)正确执行,并且依赖原实体的查询不会返回过期数据。在属性元素和嵌套映射元素中都可使用 <subselect>

We will now explore the same options using the hbm.xml structure. You can declare a persistent class using the class element. For example:

<class
        name="ClassName"
        table="tableName"
        discriminator-value="discriminator_value"
        mutable="true|false"
        schema="owner"
        catalog="catalog"
        proxy="ProxyInterface"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        select-before-update="true|false"
        polymorphism="implicit|explicit"
        where="arbitrary sql where condition"
        persister="PersisterClass"
        batch-size="N"
        optimistic-lock="none|version|dirty|all"
        lazy="(16)true|false"
        entity(17)-name="EntityName"
        check=(18)"arbitrary sql check condition"
        rowid=(19)"rowid"
        subsel(20)ect="SQL expression"
        abstra(21)ct="true|false"
        node="element-name"
/>

 

(1)name(可选):持久化类(或者接口)的 Java 全限定名。 如果这个属性不存在,Hibernate 将假定这是一个非 POJO 的实体映射。 
(2)table(可选 — 默认是类的非全限定名):对应的数据库表名。 
(3)discriminator-value(可选 — 默认和类名一样):一个用于区分不同的子类的值,在多态行为时使用。它可以接受的值包括 null 和 not null。 
(4)mutable(可选,默认值为 true):表明该类的实例是可变的或者不可变的。 
(5)schema(可选):覆盖在根 <hibernate-mapping> 元素中指定的 schema 名字。 
(6)catalog(可选):覆盖在根 <hibernate-mapping> 元素中指定的 catalog 名字。 
(7)proxy(可选):指定一个接口,在延迟装载时作为代理使用。你可以在这里使用该类自己的名字。 
(8)dynamic-update(可选,默认为 false):指定用于 UPDATE 的 SQL 将会在运行时动态生成,并且只更新那些改变过的字段。 
(9)dynamic-insert(可选,默认为 false):指定用于 INSERT 的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。 
(10)select-before-update(可选,默认为 false):指定 Hibernate 除非确定对象真正被修改了(如果该值为 true — 译注),否则不会执行 SQL UPDATE 操作。在特定场合(实际上,它只在一个瞬时对象(transient object)关联到一个新的 session 中时执行的 update() 中生效),这说明 Hibernate 会在 UPDATE 之前执行一次额外的 SQL SELECT 操作来决定是否确实需要执行 UPDATE。
(11)polymorphisms (optional - defaults to implicit): determines whether implicit or explicit query polymorphisms is used.
(12)where(可选)指定一个附加的 SQL WHERE 条件,在抓取这个类的对象时会一直增加这个条件。 
(13)persister(可选):指定一个定制的 ClassPersister。 
(14)batch-size(可选,默认是 1)指定一个用于 根据标识符(identifier)抓取实例时使用的 "batch size"(批次抓取数量)。 
(15)optimistic-lock(乐观锁定)(可选,默认是 version):决定乐观锁定的策略。 
(16)lazy(可选):通过设置 lazy="false",所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。
(17)entity-name (optional - defaults to the class name): Hibernate3 allows a class to be mapped multiple times, potentially to different tables. It also allows entity mappings that are represented by Maps or XML at the Java level. In these cases, you should provide an explicit arbitrary name for the entity. See 第 4.4 节 “动态模型(Dynamic models)” and 第 20 章 XML 映射 for more information.
(18)check(可选):这是一个 SQL 表达式, 用于为自动生成的 schema 添加多行(multi-row)约束检查。 
(19)rowid(可选):Hibernate 可以使用数据库支持的所谓的 ROWIDs,例如:Oracle 数据库,如果你设置这个可选的 rowid,Hibernate 可以使用额外的字段 rowid 实现快速更新。ROWID 是这个功能实现的重点,它代表了一个存储元组(tuple)的物理位置。 
(20)subselect(可选):它将一个不可变(immutable)并且只读的实体映射到一个数据库的子查询中。当你想用视图代替一张基本表的时候,这是有用的,但最好不要这样做。更多的介绍请看下面内容。 
(21)abstract(可选):用于在 <union-subclass> 的层次结构(hierarchies)中标识抽象超类。  

 若指明的持久化类实际上是一个接口,这也是完全可以接受的。之后你可以用元素 <subclass> 来指定该接口的实际实现类。你可以持久化任何 static(静态的)内部类。你应该使用标准的类名格式来指定类名,比如:Foo$Bar

Here is how to do a virtual view (subselect) in XML:

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

The <subselect> is available both as an attribute and a nested mapping element. 

二,个人对hibernate子查询的理解举例

1,基于视图的查询举例

   a)创建实体类(介于文章的长度,get和set方法的代码就不贴出来了)

   

@Entity
@Table(name="T_Order")
public class Order {
	@Id
	@GeneratedValue
	private int id;
	private String name;

 

@Entity
public class OrderItem {
	@Id
	@GeneratedValue
	private int id;
	private String name;
	private Double price;
	private int count;
	@ManyToOne
	private Order order;

  b)创建子查询视图(视图的字段是子查询的子集,即视图的字段要在子查询中可以找到对应的列)

@Entity
@Subselect("select o.id, o.name,sum(oi.price * oi.count) as count "
		+ "from T_Order o , OrderItem oi WHERE o.id = oi.order_id "
		+ "group by o.id , o.name ")
@Synchronize({ "T_Order", "OrderItem" })
public class OrderView {
	@Id
	private int id;
	private String name;
	private double count;

 c)创建测试类

public class OrderTest {
static SessionFactory factory = null;
	@BeforeClass
	public static void beforeClass(){
		factory = new AnnotationConfiguration().configure().buildSessionFactory();
	}
	@Test
	public void testGet(){
		Session session = factory.getCurrentSession();
		session.beginTransaction();
		Order o = new Order();
		o.setName("order1");
		session.save(o);
		for(int i = 0 ; i< 5 ; i++){
			OrderItem oi = new OrderItem();
			oi.setName("oi"+i);
			oi.setPrice(2.0);
			oi.setCount(4);
			oi.setOrder(o);
			session.save(oi);
		}
		session.getTransaction().commit();
		Session session2 = factory.getCurrentSession();
		session2.beginTransaction();
		List<OrderView> list = session2.createQuery("From OrderView ").list();
		for(OrderView ov : list){
			System.out.println(ov.getId());
			System.out.println(ov.getName());
			System.out.println(ov.getCount());
		}
		session2.getTransaction().commit();
	}
}

 

d)测试类输出结果

1
order1
40.0

 

分享到:
评论
3 楼 okhaoba 2013-01-17  
怎么传参数给subselect?
2 楼 liuxiang00435057 2012-12-25  
这个结果肯定是有问题的,ID是自增行的,这样的分组有什么用呢
1 楼 liuxiang00435057 2012-12-25  
既然是创建视图,为什么还要个ID呢,这个很难理解呢

相关推荐

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...

    Hibernate中文详细学习文档

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...

    Hibernate注释大全收藏

    Hibernate 使用 SQL Union 查询来实现这种策略。 这种策略支持双向的一对多关联,但不支持 IDENTIFY 生成器策略,因为ID必须在多个表间共享。一旦使用就不能使用AUTO和IDENTIFY生成器。 每个类层次结构一张表 @...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...

    Hibernate+中文文档

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    Hibernate教程

    使用子查询抓取(Using subselect fetching) 20.1.7. 使用延迟属性抓取(Using lazy property fetching) 20.2. 二级缓存(The Second Level Cache) 20.2.1. 缓存映射(Cache mappings) 20.2.2. 策略:只读...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     16.3.5 用带子查询的select语句整批量初始化orders集合(fetch属性为“subselect”)  16.3.6 迫切左外连接检索(fetch属性为“join”)  16.4 多对一和一对一关联的检索策略  16.4.1 迫切左外连接检索(fetch...

    hibernate总结

    2. 通过HQL/SQL 检索 hibernate query language (面向对象的查询语言) * a) 不再操纵表,它操纵的是持久化类的对象 b) 面向对象的 3. QBC ( query by criteria ) 更加面向对象 4. QBE ( query by Example ) 5....

    hibernate3.2中文文档(chm格式)

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    Hibernate 中文 html 帮助文档

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    HibernateAPI中文版.chm

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    最全Hibernate 参考文档

    19.1.5. 使用子查询抓取(Using subselect fetching) 19.1.6. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略...

    Hibernate Fetch 的作用

    正确理解hibernate fetch 的作用

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    hibernate 体系结构与配置 参考文档(html)

    14. HQL: Hibernate查询语言 14.1. 大小写敏感性问题 14.2. from子句 14.3. 关联(Association)与连接(Join) 14.4. join 语法的形式 14.5. select子句 14.6. 聚集函数 14.7. 多态查询 14.8. where子句 14.9....

    Hibernate参考文档

    使用子查询抓取(Using subselect fetching) 19.1.7. 使用延迟属性抓取(Using lazy property fetching) 19.2. 二级缓存(The Second Level Cache) 19.2.1. 缓存映射(Cache mappings) 19.2.2. 策略:只读...

    hibernate3.04中文文档.chm

    使用子查询抓取(Using subselect fetching) 20.1.7. 使用延迟属性抓取(Using lazy property fetching) 20.2. 二级缓存(The Second Level Cache) 20.2.1. 缓存映射(Cache mappings) 20.2.2. 策略:...

    hibernate配置参数详解

    hibernate配置参数详解hibernate配置参数详解hibernate配置参数详解hibernate配置参数详解

Global site tag (gtag.js) - Google Analytics