Hibernate检索策略之5.1类级别检索策略——Hibernate4究竟怎么玩

今天开始Hibernate 4的检索策略。

Hibernate的检索策略有立即检索、延迟检索和迫切左连接检索三种方式。

检索策略 类级别 关联级别
立即检索 立即加载指定的对象 立即加载与指定对象相关联的对象
延迟检索 延迟加载指定的对象 延迟加载与指定对象相关联的对象
迫切左外连接 不适用 通过左外连接加载与指定对象相关联的对象

 

 

 

 

以上是三种检索策略分别在类级别和关联级别中的不同点的说明。下面以Student与Class类多对一单向关联,举例对类级别中的检索策略进行说明。项目采用分层的方式,接近实际的开发流程。(为了方便查看放在了同一包下)

在类级别检索中只需要用到一端的实体类、service和dao层即可,在此以多端为例:

以下图分别是包的结构和表结构及数据:

其中dao层和service层只需继承基类即可,具体代码可参考(待补充)无需其他代码。

StudentUM
 1 package com.bao.sample.retrieve.strategy.umto;
 2 
 3 import javax.persistence.Entity;
 4 import javax.persistence.FetchType;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.GenerationType;
 7 import javax.persistence.Id;
 8 import javax.persistence.JoinColumn;
 9 import javax.persistence.ManyToOne;
10 import javax.persistence.Table;
11 
12 import org.hibernate.annotations.Cascade;
13 import org.hibernate.annotations.Proxy;
14 
15 import com.bao.sample.base.domain.BaseDomain;
16 
17 /**
18  * 
19  * @Description 单向关联多端
20  * @author Bob hehe198504@126.com
21  * @date 2012-8-27
22  */
23 @Proxy(lazy = true)
24 @Entity
25 @Table(name = "t_studentum")
26 public class StudentUM extends BaseDomain {
27 
28     private static final long serialVersionUID = 1L;
29 
30     private Integer id;
31 
32     private String name;
33 
34     private ClassUO classUO;
35 
36     @Id
37     @GeneratedValue(strategy = GenerationType.AUTO)
38     public Integer getId() {
39         return id;
40     }
41 
42     public void setId(Integer id) {
43         this.id = id;
44     }
45 
46     public String getName() {
47         return name;
48     }
49 
50     public void setName(String name) {
51         this.name = name;
52     }
53 
54     @ManyToOne(fetch = FetchType.LAZY)
55     @JoinColumn(name = "classid", nullable = false)
56     @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
57     public ClassUO getClassUO() {
58         return classUO;
59     }
60 
61     public void setClassUO(ClassUO classUO) {
62         this.classUO = classUO;
63     }
64 
65     public StudentUM() {
66         super();
67     }
68 
69     public StudentUM(String name, ClassUO classUO) {
70         super();
71         this.name = name;
72         this.classUO = classUO;
73     }
74 
75 }

此处类注解使用@Proxy(lazy = true),表示延迟检索指定对象。从测试类中可以看到,第22行输出“延迟加载:1”,表示执行正常,而在第23行打印那么时却报错了:org.hibernate.LazyInitializationException: could not initialize proxy - no Session。这个异常很简单,由于是延迟加载,studentUM只是一个代理类的实例而已,这个实例只初始化了标识符属性,其他属性都是null,当调用其他属性时才会执行真正的查询语句,但此时session已经关闭,无法执行执行查询,所以才会报错no Session。

 1 package com.bao.sample.retrieve.strategy.umto;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.unitils.UnitilsJUnit4;
 6 import org.unitils.spring.annotation.SpringApplicationContext;
 7 
 8 import com.bao.sample.retrieve.strategy.umto.StudentUM;
 9 import com.bao.sample.retrieve.strategy.umto.StudentUMService;
10 
11 public class StudentUMServiceTest extends UnitilsJUnit4 {
12 
13     @SpringApplicationContext( { "applicationContext.xml" })
14     private ApplicationContext applicationContext;
15 
16     @Test
17     public void loadStudent() {
18         StudentUMService studentUMService = (StudentUMService) applicationContext
19                 .getBean("studentUMService");
20         StudentUM studentUM = studentUMService.loadById(1);
21 
22         System.out.println("延迟加载:" + studentUM.getId());
23         System.out.println("报错:" + studentUM.getName());
24 
25     }
26 
27 }

如果将该注解@Proxy(lazy = true)删除,或改为@Proxy(lazy = false),再次执行测试方法,便可以看到如下输出:

 1 Hibernate: 
 2     select
 3         studentum0_.id as id10_0_,
 4         studentum0_.classid as classid10_0_,
 5         studentum0_.name as name10_0_ 
 6     from
 7         t_studentum studentum0_ 
 8     where
 9         studentum0_.id=?
10 延迟加载:1
11 报错:jack

先前报错的地方,已经有正确的信息“jack”输出了。在此之前也已经执行了查询语句。

@Proxy仅对load()方法有效,false表示立即检索;默认为true,表示延迟检索.此时不会执行select语句,仅返回代理类的实例.
以上就是在类上加Proxy注解对于session.load()方法的区别,而session.get()方法没有这个限制,get方法在类级别永远都是立即加载检索的,而load方法在类级别上默认是延迟加载的。

2012-08-29 00:43:04 听雨轩

 

 

posted @ 2012-08-28 23:10  葛一凡  阅读(496)  评论(1编辑  收藏  举报