SSH与SSM学习之hibernate22——类级别加载策略
一、说明
我们这里说的类级别加载策略,其实就是懒加载(lazy)。主要我们就是来看看使用懒加载和不适用懒加载查询有什么区别。
二、实体类与配置创建
2.1 说明
我们这里使用的关系是公司和员工一对多的关系。公司使用Company,员工使用 Employee。
2.2 Company.java 实体类
package com.qwm.hibernate03.domain;
import java.util.HashSet;
import java.util.Set;
/**
* @author:qiwenming
* @date:2017/9/21 0021 0:12
* @description:
* 公司实体
*/
public class Company {
private Long id;
private String name;
//一对多
private Set<Employee> emps = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
}
@Override
public String toString() {
return "Company{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
2.3 Company.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.qwm.hibernate03.domain" >
<class name="Company" table="tb_company" lazy="true">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" ></property>
<!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<set name="emps">
<key column="com_id"></key>
<one-to-many class="Employee"></one-to-many>
</set>
</class>
</hibernate-mapping>
2.4 Employee.java 实体类
package com.qwm.hibernate03.domain;
/**
* @author:qiwenming
* @date:2017/9/21 0021 0:14
* @description:
* y员工
*/
public class Employee {
private Long em_id;
private String name;
private Company company;
public Long getEm_id() {
return em_id;
}
public void setEm_id(Long em_id) {
this.em_id = em_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
@Override
public String toString() {
return "Employee{" +
"em_id=" + em_id +
", name='" + name + '\'' +
'}';
}
}
2.5 Employee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.qwm.hibernate03.domain" >
<class name="Employee" table="tb_employee" >
<id name="em_id" >
<generator class="native"></generator>
</id>
<property name="name" ></property>
<!-- 多对一 -->
<!--
name属性:引用属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<many-to-one name="company" column="com_id" class="Company"/>
</class>
</hibernate-mapping>
2.6 添加测试数据的代码
/**
* 用户添加测试数据而已
*/
@Test
public void test(){
Session session = HibernateUtils.openSession();
Transaction t = session.beginTransaction();
//-------------------------------------------
Company c1 = new Company();
c1.setName("百鸟公司");
Company c2 = new Company();
c2.setName("新合伙公司");
Employee e11 = new Employee();
e11.setName("李晓飞");
e11.setCompany(c1);
Employee e12 = new Employee();
e12.setName("周小龙");
e12.setCompany(c1);
Employee e21 = new Employee();
e21.setName("张大波");
e21.setCompany(c2);
Employee e22 = new Employee();
e22.setName("吴人用");
e22.setCompany(c2);
Employee e23 = new Employee();
e23.setName("晓峰");
e23.setCompany(c2);
//保存到数据库
session.save(c1);
session.save(c2);
session.save(e11);
session.save(e12);
session.save(e21);
session.save(e22);
session.save(e23);
//---------------------------------------------
t.commit();
session.close();
}
三、get测试
3.1 实例代码
/**
* get方法 : 立即加载.执行方法时立即发送sql语句查询结果
*/
@Test
public void test1(){
Session session = HibernateUtils.openSession();
Transaction t = session.beginTransaction();
//-------------------------------------------
Company c = session.get(Company.class,1L);
System.out.println("-------------我是分割线--------------");
System.out.println(c);
//---------------------------------------------
t.commit();
session.close();
}
3.2 结果
Hibernate:
select
company0_.id as id1_0_0_,
company0_.name as name2_0_0_
from
tb_company company0_
where
company0_.id=?
-------------我是分割线--------------
Company{id=1, name='百鸟公司'}
3.3 结论
get方法 : 立即加载.执行方法时立即发送sql语句查询结果
四、使用懒加载测试
默认就是使用懒加载,或者修改我们 Company.hbm.xml ,添加我们懒加载属性(lazy)
.......
<class name="Company" table="tb_company" lazy="true">
.......
</class>
.......
4.1 实例代码
/**
* load方法(默认):是在执行时,不发送任何sql语句.返回一个对象.使用该对象时,才执行查询.
* 延迟加载: 仅仅获得没有使用.不会查询.在使用时才进行查询.
* 是否对类进行延迟加载: 可以通过在class元素上配置lazy属性来控制.
* lazy:true 加载时,不查询.使用时才查询b
* lazy:false 加载时立即查询.
*/
@Test
public void test2(){
Session session = HibernateUtils.openSession();
Transaction t = session.beginTransaction();
//-------------------------------------------
Company c = session.load(Company.class,1L);
System.out.println("-------------我是分割线--------------");
System.out.println(c);
//---------------------------------------------
t.commit();
session.close();
}
4.2 结果
-------------我是分割线--------------
Hibernate:
select
company0_.id as id1_0_0_,
company0_.name as name2_0_0_
from
tb_company company0_
where
company0_.id=?
Company{id=1, name='百鸟公司'}
4.3 结论
load方法(默认):是在执行时,不发送任何sql语句.返回一个对象.使用该对象时,才执行查询.
返回的其实是一个代理对象
五、不使用懒加载测试
测试代码和 四 是一样的
5.1 修改配置文件
.......
<class name="Company" table="tb_company" lazy="false">
.......
</class>
.......
5.2 结果
Hibernate:
select
company0_.id as id1_0_0_,
company0_.name as name2_0_0_
from
tb_company company0_
where
company0_.id=?
-------------我是分割线--------------
Company{id=1, name='百鸟公司'}
5.3 结论
lazy:false 加载时立即查询.
和get方法是一样的
返回的是一个我们查询的对象,不是代理对象