lazy,延迟加载
Lazy的有效期:只有在session打开的时候才有效;session关闭后lazy就没效了。
lazy策略可以用在:
* <class>标签上:可以取值true/false
* <property>标签上,可以取值true/false,这个特性需要类增强
* <set>/<list>等集合上,可以取值为true/false/extra
* <one-to-one>/<many-to-one>等标签上,可以取值false/proxy/no-proxy
6.1 get和load的区别:
* get不支持延迟加载,而load支持。
* 当查询特定的数据库中不存在的数据时,get会返回null,而load则抛出异常。
6.2 类(Class)的延迟加载:
* 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性)
* 如果lazy的属性值为true,那么在使用load方法加载数据时,只有确实用到数据的时候才会发出sql语句;这样有可能减少系统的开销。
* //不会发出查询sql
System.out.println("group id=" + group.getId());
这里有一个问题,为什么加载主键的时候不需要发出sql语句。
6.3 集合(collection)的延迟加载:可以取值true,false,extra
* 保持集合上的lazy的默认值,此时的效果和lazy="extra"是基本一样的。
* 设置集合上的lazy=extra,此时的效果和lazy属性的默认值是基本一样的。但是推荐使用这个属性值,因为在统计时这种情况显得比较智能。当然延迟是有效果的。
* 设置集合上的lazy=false
true:默认取值,它的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其集合元素的数据
false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据
extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate
并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据
6.4 Hibernate单端关联懒加载策略:即在<one-to-one>/<many-to-one>标签上可以配置
懒加载策略。可以取值为:false/proxy/no-proxy
false:取消懒加载策略,即在加载对象的同时,发出查询语句,加载其关联对象
proxy:这是hibernate对单端关联的默认懒加载策略,即只有在调用到其关联对象的方法的时候才真正发出查询语句查询其对象数据,其关联对象是代理类
no-proxy:这种懒加载特性需要对类进行增强,使用no-proxy,其关联对象不是代理类
注意:在class标签上配置的lazy属性不会影响到关联对象!!!
- <hibernate-mapping>
- <class name="com.bjsxt.hibernate.Group" table="t_group">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- </class>
- </hibernate-mapping>
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
- package com.bjsxt.hibernate;
- import org.hibernate.Session;
- import com.bjsxt.hibernate.Group;
- import com.bjsxt.hibernate.HibernateUtils;
- public class InitData {
- public static void main(String[] args) {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- session.beginTransaction();
- Group group = new Group();
- group.setName("java开发组");
- session.save(group);
- session.getTransaction().commit();
- }catch(Exception e) {
- e.printStackTrace();
- session.getTransaction().rollback();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- }
package com.bjsxt.hibernate;
import org.hibernate.Session;
import com.bjsxt.hibernate.Group;
import com.bjsxt.hibernate.HibernateUtils;
public class InitData {
public static void main(String[] args) {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Group group = new Group();
group.setName("java开发组");
session.save(group);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
- package com.bjsxt.hibernate;
- import org.hibernate.Session;
- import junit.framework.TestCase;
- /**
- * 运行本单元测试的前提条件:
- * 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性)
- *
- * @author Administrator
- *
- */
- public class ClassLazyTest extends TestCase {
- public void testLoadGroup1() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Group group = (Group)session.load(Group.class, 1);
- //不会发出查询sql
- System.out.println("group id=" + group.getId());
- //发出查询sql,加载数据到Group
- System.out.println("group name=" + group.getName());
- //不会发出查询sql
- System.out.println("group name=" + group.getName());
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testLoadGroup2() {
- Session session = null;
- Group group = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- group = (Group)session.load(Group.class, 1);
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- //不能正常输出,抛出了 LazyInitializationException,因为session已经关闭了
- //注意:Hibernate支持Lazy策略,只有session打开状态才有效
- System.out.println("group name=" + group.getName());
- }
- }
package com.bjsxt.hibernate;
import org.hibernate.Session;
import junit.framework.TestCase;
/**
* 运行本单元测试的前提条件:
* 设置<class>标签中的lazy="true",或是保持默认(即不配置lazy属性)
*
* @author Administrator
*
*/
public class ClassLazyTest extends TestCase {
public void testLoadGroup1() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Group group = (Group)session.load(Group.class, 1);
//不会发出查询sql
System.out.println("group id=" + group.getId());
//发出查询sql,加载数据到Group
System.out.println("group name=" + group.getName());
//不会发出查询sql
System.out.println("group name=" + group.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoadGroup2() {
Session session = null;
Group group = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
group = (Group)session.load(Group.class, 1);
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
//不能正常输出,抛出了 LazyInitializationException,因为session已经关闭了
//注意:Hibernate支持Lazy策略,只有session打开状态才有效
System.out.println("group name=" + group.getName());
}
}
---------------------------------------------------------------------
集合类测试
- <hibernate-mapping>
- <class name="com.bjsxt.hibernate.Classes" table="t_classes">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <!--
- <set name="students" cascade="all" order-by="id">
- -->
- <set name="students" lazy="extra">
- <key column="classid"/>
- <one-to-many class="com.bjsxt.hibernate.Student"/>
- </set>
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="com.bjsxt.hibernate.Student" table="t_student">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- </class>
- </hibernate-mapping>
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!--
<set name="students" cascade="all" order-by="id">
-->
<set name="students" lazy="extra">
<key column="classid"/>
<one-to-many class="com.bjsxt.hibernate.Student"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
- package com.bjsxt.hibernate;
- import java.util.Iterator;
- import java.util.Set;
- import org.hibernate.Session;
- import junit.framework.TestCase;
- /**
- * 保持lazy的默认值
- * @author Administrator
- *
- */
- public class CollectionLazyTest1 extends TestCase {
- public void testLoadClasses1() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出一条查询sql,加载数据到classes
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //会发出一条查询sql,加载数据到Students
- for (Iterator iter = students.iterator(); iter.hasNext();) {
- Student student = (Student)iter.next();
- System.out.println(student.getName());
- }
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testLoadClasses2() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出一条查询sql,加载数据到classes
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //会发出一条查询sql,加载全部的数据到Students
- System.out.println(students.size());
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- }
package com.bjsxt.hibernate;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import junit.framework.TestCase;
/**
* 保持lazy的默认值
* @author Administrator
*
*/
public class CollectionLazyTest1 extends TestCase {
public void testLoadClasses1() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出一条查询sql,加载数据到classes
System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
//不会发出查询sql
Set students = classes.getStudents();
//会发出一条查询sql,加载数据到Students
for (Iterator iter = students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoadClasses2() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出一条查询sql,加载数据到classes
System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
//不会发出查询sql
Set students = classes.getStudents();
//会发出一条查询sql,加载全部的数据到Students
System.out.println(students.size());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
}
- package com.bjsxt.hibernate;
- import java.util.Iterator;
- import java.util.Set;
- import org.hibernate.Session;
- import junit.framework.TestCase;
- /**
- * 设置集合上的lazy=false
- * @author Administrator
- *
- */
- public class CollectionLazyTest2 extends TestCase {
- public void testLoadClasses1() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出两条查询sql,加载数据到classes和Students中
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //不会发出查询sql
- for (Iterator iter = students.iterator(); iter.hasNext();) {
- Student student = (Student)iter.next();
- System.out.println(student.getName());
- }
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testLoadClasses2() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出两条查询sql,加载数据到classes和Students中
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //不会发出查询sql
- System.out.println(students.size());
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- }
package com.bjsxt.hibernate;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import junit.framework.TestCase;
/**
* 设置集合上的lazy=false
* @author Administrator
*
*/
public class CollectionLazyTest2 extends TestCase {
public void testLoadClasses1() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出两条查询sql,加载数据到classes和Students中
System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
//不会发出查询sql
Set students = classes.getStudents();
//不会发出查询sql
for (Iterator iter = students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoadClasses2() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出两条查询sql,加载数据到classes和Students中
System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
//不会发出查询sql
Set students = classes.getStudents();
//不会发出查询sql
System.out.println(students.size());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
}
- package com.bjsxt.hibernate;
- import java.util.Iterator;
- import java.util.Set;
- import org.hibernate.Session;
- import junit.framework.TestCase;
- /**
- * 设置集合上的lazy=extra
- * @author Administrator
- *
- */
- public class CollectionLazyTest3 extends TestCase {
- public void testLoadClasses1() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出一条查询sql,加载数据到classes
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //会发出一条查询sql,加载数据到students
- for (Iterator iter = students.iterator(); iter.hasNext();) {
- Student student = (Student)iter.next();
- System.out.println(student.getName());
- }
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- public void testLoadClasses2() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- Classes classes = (Classes)session.load(Classes.class, 1);
- //会发出一条查询sql,加载数据到classes
- System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
- //不会发出查询sql
- Set students = classes.getStudents();
- //会发出一条较为智能的查询sql,如:
- //select count(id) from t_student where classid =?
- System.out.println(students.size());
- }catch(Exception e) {
- e.printStackTrace();
- }finally {
- HibernateUtils.closeSession(session);
- }
- }
- }
package com.bjsxt.hibernate;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import junit.framework.TestCase;
/**
* 设置集合上的lazy=extra
* @author Administrator
*
*/
public class CollectionLazyTest3 extends TestCase {
public void testLoadClasses1() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出一条查询sql,加载数据到classes
System.out.println("班级:【" + classes.getName() + "】 拥有的学生:");
//不会发出查询sql
Set students = classes.getStudents();
//会发出一条查询sql,加载数据到students
for (Iterator iter = students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoadClasses2() {
Session session = null;
try {
session = HibernateUtils.getSession();
//不会发出查询sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出一条查询sql,加载数据到classes
System.out.println("班级:【" + classes.getName() + "】 拥有的学生总数:");
//不会发出查询sql
Set students = classes.getStudents();
//会发出一条较为智能的查询sql,如:
//select count(id) from t_student where classid =?
System.out.println(students.size());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
}
----------------------------------------------------------------
单端关联加载
- <hibernate-mapping>
- <class name="com.bjsxt.hibernate.Group" table="t_group">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="com.bjsxt.hibernate.User" table="t_user" >
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <!--
- <many-to-one name="group" column="relatedGroup" />
- -->
- <many-to-one name="group" column="relatedGroup"/>
- </class>
- </hibernate-mapping>
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.bjsxt.hibernate.User" table="t_user" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!--
<many-to-one name="group" column="relatedGroup" />
-->
<many-to-one name="group" column="relatedGroup"/>
</class>
</hibernate-mapping>
- package com.bjsxt.hibernate;
- import org.hibernate.Session;
- import junit.framework.TestCase;
- /**
- * 所有lazy的属性默认
- * @author Administrator
- *
- */
- public class SingleEndTest1 extends TestCase {
- public void testLoadUser() {
- Session session = null;
- try {
- session = HibernateUtils.getSession();
- //不会发出查询sql
- User user = (User)session.load(User.class, 2);
- //会发出一条查询sql,转载数据到User
- System.out.println("user name=" + user.getName());
- //不会发出查询sql
- Group group = user.getGroup();