`
software_developer
  • 浏览: 34761 次
  • 性别: 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笔记

    ### Hibernate笔记 #### 一、概述 Hibernate 是一个开源的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互过程。通过使用Hibernate,开发者...希望这些笔记能够对学习和使用Hibernate有所帮助。

    hibernate学习笔记

    ### Hibernate学习笔记:对象/关系数据库映射(二)——集合映射 #### 1. 集合映射概述 在对象/关系映射(ORM)领域中,Hibernate 是一个非常强大的工具,它能够帮助开发者高效地进行 Java 对象与数据库记录之间的...

    hibernate子查询

    这意味着你需要为这个临时的子查询结果创建一个新的Java类,然后在Hibernate映射文件中定义这个类,使用`subselect`属性指定子查询的SQL语句。这样,Hibernate就会根据这个子查询来获取和管理数据,而不是直接操作...

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

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

    day36 06-Hibernate抓取策略:set集合上的抓取策略

    例如,对于`@OneToMany(mappedBy="parent", fetch=FetchType.SUBSELECT)`,Hibernate会在查询父对象的同时,用子查询获取所有子对象。这种方式可以避免N+1查询,但可能对数据库性能有一定影响,因为需要执行额外的...

    Hibernate Fetch 的作用

    在Hibernate查询语言(HQL)或原生SQL查询中,可以使用`Fetch`关键字来显式指定关联对象的加载。例如,在上面的代码片段中,通过`left outer join fetch parent.childs`语句,我们告诉Hibernate在加载`Parent`实体时...

    Hibernate教程24_Hibernate的1+N问题

    2. 使用FetchType: - FetchType.LAZY:表示懒加载,延迟到需要时再加载关联数据。 - FetchType.EAGER:表示急加载,与主对象一起立即加载关联数据。 3. HQL和 Criteria API的优化: - 在HQL查询中使用`JOIN ...

    如何提高hibernate性能

    使用HQL(Hibernate Query Language)或Criteria API进行查询,它们可以更好地利用Hibernate的优化机制,减少与数据库的交互次数。 9. **避免N+1查询问题**: 在关联查询中,确保一次获取所需的所有关联数据,以...

    day36 07-Hibernate抓取策略:many-to-one上的抓取策略

    2. **@BatchSize**:这个注解允许我们指定在一次查询中加载多少个关联对象,以平衡内存使用和数据库交互。例如,如果一个用户有成千上万的朋友,我们可以设置批处理大小为100,每次加载100个朋友。 3. **JOIN**:在...

    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之数据加载方式

    - **HQL(Hibernate Query Language)**:Hibernate的专用查询语言,类似SQL,但更面向对象,支持复杂的查询条件和结果映射。 - **Criteria API**:提供了一种基于对象的查询方式,更加灵活且类型安全。 - **...

    hibernate配置参数详解

    开启后,Hibernate会在运行时收集一些统计信息,如查询次数、缓存命中率等,有助于监控和优化应用性能。 11. **`hibernate.use_identifer_rollback`**: 在回滚时是否使用标识符。 ```properties hibernate.use_...

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

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

    精通 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...

    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. 策略:只读...

Global site tag (gtag.js) - Google Analytics