lazy的概念:在正真使用某个对象的时候才正真的去创建,对于hibernate才会正真的发出sql语句,去加载该对象
hibernate的lazy策略可以使用在:
* <class>标签上,可以取值:true/false
* <property>标签上,可以取值:true/false,需要类增强工具,对字节码进行修改
* <set>/<list>标签上,用得最多.可以取值:true/false/extra
* <many-to-one>/<one-to-one>单端关联标签上,单端关联即是对端为one,可以取值:false/proxy/noproxy,proxy使用CgLib代理,noproxy使用类增强工具,对字节码进行修改,把代码改了,先执行它的东西,没有真正的去获取数据库,就跟你自己写的代理一样
注意点:
hibernate的lazy策略必须在session打开状态下有效
用在 <class>标签上,可以取值:true/false
<class>上的lazy只影响普通属性
public class LazyForClassTest extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
User user = (User)session.load(User.class, 1);
//不会发出sql
System.out.println("user.id=" + user.getId());
//会发出sql,一次性的把所有的普通属性全查上来
System.out.println("user.name=" + user.getName());
//不会发出sql
System.out.println("user.password=" + user.getPassword());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
User user = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
user = (User)session.load(User.class, 1);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
//不能正确输出,抛出了LazyInitializationException异常
//原因在于session已经关闭,相当于Connection释放了
//hibernate的lazy策略必须在session打开状态下有效
System.out.println("user.name=" + user.getName());
}
}
.
<set>/<list>标签上,用得最多.可以取值:true/false/extra
保持默认情况下,即set上的lazy为true
/**
* 保持默认
* @author Administrator
*
*/
public class CollectionLazyTest1 extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出sql,但只发出查询班级的普通属性
System.out.println("classes.name=" + classes.getName());
//不会发出sql,因为<class>标签上的lazy不会影响集合上的lazy特性,<class>上的lazy只会影响普通属性
Set students = classes.getStudents();
//会发出sql
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println("student.name=" +student.getName());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出sql
System.out.println("classes.name=" + classes.getName());
//不会发出sql
Set students = classes.getStudents();
//会发出查询该班级全部学生的sql语句,存在效率问题
System.out.println("count=" + students.size());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
即set上的lazy为false,其他默认
/**
* 将<set>标签上的lazy设置为false,其他默认
* @author Administrator
*
*/
public class CollectionLazyTest2 extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出两条查询语句,分别查询班级和学生
System.out.println("classes.name=" + classes.getName());
//不会发出sql
Set students = classes.getStudents();
//不会发出sql
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println("student.name=" +student.getName());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出两条查询语句,分别查询班级和学生
System.out.println("classes.name=" + classes.getName());
//不会发出sql
Set students = classes.getStudents();
//不会发出sql
System.out.println("count=" + students.size());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
set上的lazy为extra,其他默认
/**
* 将<set>标签上的lazy设置为extra,其他默认
* @author Administrator
*
*/
public class CollectionLazyTest3 extends TestCase {
public void testLoad1() {//这里跟默认的时候是一样的
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出sql
System.out.println("classes.name=" + classes.getName());
//不会发出sql
Set students = classes.getStudents();
//会发出sql
for (Iterator iter=students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println("student.name=" +student.getName());
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
Classes classes = (Classes)session.load(Classes.class, 1);
//会发出sql
System.out.println("classes.name=" + classes.getName());
//不会发出sql
Set students = classes.getStudents();
//会发出一条智能的sql,如:
//Hibernate: select count(id) from t_student where classesid =?
//建议集合上的lazy设置为extra
System.out.println("count=" + students.size());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
<many-to-one>/<one-to-one>单端关联标签上使用lazy
/**
* 保持默认
* @author Administrator
*
*/
public class SingleEndLazyTest1 extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
User user = (User)session.load(User.class, 1);
//会发出sql
System.out.println("user.name=" + user.getName());
//不会发出sql
Group group = user.getGroup();
//会发出sql
System.out.println("user.group.name=" + group.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
/**
* 设置<many-to-one>上的lazy为false,其他默认
* @author Administrator
*
*/
public class SingleEndLazyTest2 extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出sql
User user = (User)session.load(User.class, 1);
//发出了两条sql语句,分别加载用户和组
System.out.println("user.name=" + user.getName());
//不会发出sql
Group group = user.getGroup();
//不会发出sql
System.out.println("user.group.name=" + group.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
/**
* 将<class>标签上的lazy设置为false,其他默认
* @author Administrator
*
*/
public class SingleEndLazyTest3 extends TestCase {
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//会发出sql
User user = (User)session.load(User.class, 1);
//不会发出sql
System.out.println("user.name=" + user.getName());
//不会发出sql,因为<class>上的lazy只影响普通属性
Group group = user.getGroup();
//会发出sql
System.out.println("user.group.name=" + group.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
.特别注意点:<class>上的lazy只影响普通属性 ,它是影响不到它里面的集合的lazy属性的.也不会影响单端关联对象的lazy策略