当前位置: 首页 > 工具软件 > Lazy > 使用案例 >

lazy总结

柴兴修
2023-12-01

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

 类似资料: