一、hibernate的延迟加载与动态代理
1、hibernate中的延迟加载:get VS load
我们知道,在hibernate方法中,直接涉及到延迟加载的方法有get和load,使用get时,不会延迟加载,load则反之。另外,在many-to-one等关系配置中,我们也可以通过lazy属性设置是否延迟加载,这是我们对hibernate最直观的认识。
2、现象解释----动态代理机制
其实在hibernate设置延迟加载后,hibernate返回给我们的对象(要延迟加载的对象)是一个代理对象,并不是真实的对象,该对象没有真实对象的数据,只有真正需要用到对象数据(调用getter等方法时)时,才会触发hibernate去数据库查对应数据,而且查回来的数据不会存储在代理对象中,所以这些数据是无法在调试窗口查看到的。
也就是说,我们user变量仅仅是一个代理类,target才是真正数据库中获取的数据。当我们在调用getter方法时,hibernate会利用动态代理的方法,直接调用target中的getter方法返回对应的值。这样也解释了为什么hibernate可以延迟加载:通过代理类进行加载时间的控制,在外界正真调用getter等方法操作数据时才会对相应的方法进行拦截,然后读取数据库。hibernate的查询操作大概就是在invoke方法中调用正式的getter等获取数据方法前进行的,动态代理帮我们拦截了getter等获取数据方法并对应地在这之前进行了数据查询等操作。
java中为什么只能通过接口实现动态代理?
这是因为Proxy的newInstance方法限制的,更本质的原因其实就是java不支持多继承,所以代理对象不得不通过操作接口操作真实对象。
A、实体对象的延迟加载:session.load()方法,会返回实体对象的代理类对象
B、集合类型的延迟加载:意义是最为重大的,因为这有可能使性能得到大幅度的提高,因此对JDK Collection进行独立实现,要对集合类型中的实体也指定缓存策略。
C、 属性延迟加载:大数据对象的读取本身会带来很大的性能开销,
注:借鉴包含但不限于以下
http://www.cnblogs.com/lcplcpjava/p/6759859.html
https://blog.csdn.net/jojoy_828/article/details/1911325