当前位置 博文首页 > 程序员石磊:Hibernate One to Many 迟延加载分析

    程序员石磊:Hibernate One to Many 迟延加载分析

    作者:[db:作者] 时间:2021-08-08 19:20

    One to Many

    1: Oneto Many,默认是采用延迟加载的(lazy=true),因为很多情况下,当我们获取到One的一方后,Many的一方并非立即需要的,当我们经常只需要One的一方的时候,延迟加载就很有意义了.

    2:Hibernate 中的延迟加载(lazy loading),当我们在程序中获取到了一的一方,但是不需要多的一方,那么使用延迟加载就是非常适合的.

    3:当我们One和Many都要同时需要的时候,我们可以将One的一方的hbm.xml中用于保存Many的Set元素的lazy改为false

    One to Many的延迟加载分析

    当我们通过通过Session.get()查询到One的一方后,其中用于保存Many的Set其实是一个代理,其类型为org.hibernate.collection.PersistentSet, PersistentSet 实现了Java.util.Set接口,并内置了一个用于存放实际数据的HashSet,初始时为空,当真正要访问这个集合的元素时,如调用Java.util.Set#iterator()#toArray() #containsAll(),#toString,#equal()#hashCode等要真正访问集合的元素的方法的时候,程序才主要发出SQL语句,真正加载Many一方,并且一次读取完Many一方的所有元素.

    PersistentSet 实现了Java.util.Set接口,并内置了一个HashSet实例,PersistentSet代理了Java.util.Set的#iterator()#toArray()

    ?#containsAll(),#toString等方法: 而代理的过程很简单:

    若要访问到Many的数据,则先加载Many的所有元素,再简单调用被代理的方法!

    这里也是应用到"代理模式"的思想..框架里,这个模式很常用......

    在Hibernate里,延迟加载基本是用"代理模式"实现的!

    如:

    1. public?class?PersistentSet?extendsAbstractPersistentCollection?implements?java.util.Set?{?
    2. 。。。。。。。。。。。。。。?
    3. ? ?
    4. ? ? ? ?publicString?toString()?{?
    5. ? ? ? ? ? ? ? read();? ?//先加载Many一方??
    6. ? ? ? ? ? ? ??return?set.toString();?
    7. ? ? ? ?}?
    8. ? ?
    9. 。。。。。。。。。。。?
    10. }?

    再看看read()方法:

    1. public?abstract?classAbstractPersistentCollection?implementsSerializable,?PersistentCollection?{?
    2. ? ?
    3. …………………………………?
    4. ? ??/**?
    5. ? ? *?Called?by?any?read-only?method?of?the?collection?interface?
    6. ? ? */?
    7. ? ??protected?final?void?read()?{?
    8. ? ? ? ? ? initialize(false);?
    9. ? ? }?
    10. ? ?
    11. ? ? protectedfinal?void?initialize(boolean?writing)?{?
    12. ? ? ? ? ? ? ??if?(!initialized)?{?
    13. ? ? ? ? ? ? ? ? ? ? ?if(initializing)?{?
    14. ? ? ? ? ? ??throw?new?LazyInitializationException("illegal?access?toloading?collection");?
    15. ? ? ? ? ? ? ? ? ? ? ?}?
    16. ? ? ? ? ? ? ? ? ? ? ?//检查与数据库的连接??
    17. ? ? ? ? ? ? ? ? ? ? ?throwLazyInitializationExceptionIfNotConnected();?
    18. ? ? ? ? ? ? ? ? ? ? ?
    19. ? ? ? ? ? ? ? ? ? ? ?//这里真正加载Many??
    20. ? ? ? ? ? ? ?session.initializeCollection(this,?writing);?
    21. ? ? ? ? ? ? ? }?
    22. ? ? ? ? }?
    23. ? ?
    24. …………………………………….?
    25. ? ?
    26. }?
    cs