一对一对象的懒加载,对于主的一方,lazy是无效的,它在访问数据的时候,还是会利用左连接,把主从表的数据
全部查询一遍 但是对于从对象,默认的是懒加载 lazy=true 如果你需要从对象的数据,如果你通过子实体和id直接去查询
从实体 get()方法 它只查询从对象的数据,并不会去查询主对象的数据
一对多 懒加载 重点
缺省的是懒加载的 比说说部门与员工 ,一个部门可能有几千员工
比说我我们增加一个部门 同时增加几名员工 我们查询部门的信息
package vo.util.test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import vo.util.HibernateUtil;
import vo.util.bean.Department;
import vo.util.bean.Employee;
public class OneToMany {
/**
* @param args
*/
public static void main(String[] args) {
add();
query(1);
}
static Department add(){
Session session = null;
Transaction tx = null;
try{
session =HibernateUtil.getSession();
tx = session.beginTransaction();
//…你的代码save,delete,update,get…
Department dpart=new Department();
dpart.setName("政企事业部");
Employee em1=new Employee();
em1.setName("员工李小仙");
em1.setDerpartment(dpart);
Employee em2=new Employee();
em2.setName("员工张小三");
em2.setDerpartment(dpart);
Map<String,Employee> ems=new HashMap<String, Employee>();
ems.put(em1.getName(), em1);
ems.put(em2.getName(), em2);
dpart.setEms(ems);
session.save(dpart);
session.save(em1);
session.save(em2);
tx.commit();
return dpart;
}finally{
if(session != null)session.close();
}
}
static Department query(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
//这里只是调用部门的实体类进行查询
Department d=(Department)session.get(Department.class, id);
//System.out.println(d.getEms());
return d;
}finally{
if(session != null)session.close();
}
}
}
控制台输出
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
打开连接成功!Hibernate: insert into Department (name) values (?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: update Employee set depaer_id=?, name=? where id=?
Hibernate: update Employee set depaer_id=?, name=? where id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
发现 只是查询了部门的信息 并没有去查询员工的信息 说明默认的情况下 一对多 一的一方是懒加载的
然后我们看部门的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="vo.util.bean">
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 配置一对多的映射关系 -->
<!--
<set name="ems">
-->
<!-- 关联关系的外键 -->
<!--
<key column="depaer_id"/>
-->
<!-- 关联关系的实体类配置 -->
<!--
<one-to-many class="Employee" />
</set>
-->
<map name="ems">
<key column="depaer_id"/>
<map-key type="string" column="name"/>
<one-to-many class="Employee"/>
</map>
</class>
</hibernate-mapping>
部门这边的set节点我们没有去配置
当我们去通过部门去访问员工信息的时候
才会去select
给查询的方法加上 System.out.println(d.getEms());
就会去查询员工信息 了
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
打开连接成功!Hibernate: insert into Department (name) values (?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: update Employee set depaer_id=?, name=? where id=?
Hibernate: update Employee set depaer_id=?, name=? where id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
Hibernate: select ems0_.depaer_id as depaer3_1_, ems0_.id as id1_, ems0_.name as name1_, ems0_.id as id1_0_, ems0_.name as name1_0_, ems0_.depaer_id as depaer3_1_0_ from Employee ems0_ where ems0_.depaer_id=?
{}
总结 通过asm和cglib二个包实现;Domain是非final的。
1.session.load懒加载。
2.one-to-one(元素)懒加载:
必需同时满足下面三个条件时才能实现懒加载
(主表不能有constrained=true,所以主表没有懒加载)
lazy!=false 2)constrained=true 3)fetch=select
3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select
4.many-to-one (元素) :1)lazy!=false 2)fetch=select
5.many-to-many (元素) :1)lazy!=false 2)fetch=select
6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,
访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,
或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。