lazy总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Kotlinlazy是一种以惰性方式初始化属性的机制。它可以在属性第一次使用或调用时进行初始化,而不是在定义属性时立即初始化。这种机制能够提高代码的效率,并且特别适用于那些在定义时无法确定初始值的情况,比如在Android的生命周期驱动属性。使用lazy机制可以延迟属性的初始化,直到它真正被需要。 在Kotlin,可以通过将属性声明为lazy来使用这种机制。使用lazy函数,我们可以定义一个lambda表达式来初始化属性。该lambda表达式在属性第一次被使用或调用时被执行,并且结果被缓存起来,以便之后的使用。这种机制确保了属性的初始化只会在需要时进行,而不会浪费不必要的早期初始化。 下面是使用lazy的示例代码: ```kotlin val myLazyProperty: String by lazy { // 这里是属性的初始化代码 // 可以是任何复杂的逻辑 "Initializing my lazy property" } fun main() { // 第一次使用属性,进行初始化 println(myLazyProperty) // 输出:Initializing my lazy property // 再次使用属性,不进行初始化,直接使用缓存的结果 println(myLazyProperty) // 输出:Initializing my lazy property } ``` 在上述示例,myLazyProperty是一个使用lazy机制的属性。当第一次访问该属性时,lambda表达式会被执行,属性会被初始化为"Initializing my lazy property"。之后再次访问该属性时,不会再执行lambda表达式,而是直接使用已经缓存的结果。 总结起来,Kotlinlazy机制允许我们以惰性方式初始化属性,只有在需要时才进行初始化。这种机制可以提高代码的效率,并且特别适用于那些无法在定义时确定初始值的情况[1]。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yjsuge

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值