一对多关系(关联):一个Customer(客户)对应多个LinkMan(联系人)
Test.java(集合级别,通过Customer(一)获取关联的LinkMan(多、集合)):
package cn.xxx.demo;
import java.util.List;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.xxx.domain.Customer;
import cn.xxx.domain.LinkMan;
import cn.xxx.utils.HibernateUtils;
// 关联级别的懒加载(抓取策略:如何获取关联对象的策略) (一对多、多对多 对象产生关联)
public class Test {
@Test
//集合级别的关联 (多对一中的一)
//fetch:select(默认值) 单表查询
//lazy:true(默认值) 使用时才加载关联对象(集合数据)。
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Customer c = session.get(Customer.class, 2l); // get立即加载Customer对象。(不加载关联对象LinkMan)
Set<LinkMan> linkMens = c.getLinkMens(); // lazy:true 不会立即加载关联对象LinkMan
System.out.println(linkMens); // 在使用LinkMan时,才去加载LinkMan。
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//集合级别的关联
//fetch:select 单表查询
//lazy:false 立即加载关联对象(集合数据)
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Customer c = session.get(Customer.class, 2l); // get立即加载Customer对象。 lazy:false,同时立即加载关联的LinkMan对象。
Set<LinkMan> linkMens = c.getLinkMens();
System.out.println(linkMens);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//集合级别的关联
//fetch:select 单表查询
//lazy:extra 极其懒惰,与懒加载效果基本一致。 如果只获得集合的size,只会"select count(id)..",并不会查询完整的数据。
public void fun3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Customer c = session.get(Customer.class, 2l); // get立即加载Customer对象。(不加载关联对象LinkMan)
Set<LinkMan> linkMens = c.getLinkMens(); // lazy:extra 不会立即加载关联对象LinkMan
System.out.println(linkMens.size()); // 在获取size时;只会"select count(id)..",不会查询完整的LinkMan对象。
System.out.println(linkMens); // 在使用LinkMan时,才会查询完整的LinkMan对象。
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//集合级别的关联
//fetch:join 多表查询(关联的对象也会同时加载)
//lazy:true|false|extra 失效.立即加载.
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Customer c = session.get(Customer.class, 2l); // get立即查询Customer。fetch:join 多表查询,关联的LinkMan也会立即加载。
Set<LinkMan> linkMens = c.getLinkMens();
System.out.println(linkMens.size());
System.out.println(linkMens);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//fetch:subselect 子查询(select .. where id in (select ..)) (多表查询换成 单表查询和子查询,两次查询)
//lazy:true 懒加载
public void fun5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list(); // 查询所有的Customer(单表查询)。 不会立即查询关联的LinkMan对象。
for(Customer c:list){
System.out.println(c);
//lazy:true 懒加载。 使用关联对象LinkMan时,才去加载LinkMan。
System.out.println(c.getLinkMens().size()); // 查询所有Customer关联的所有LinkMan对象。 (子查询)
System.out.println(c.getLinkMens());
}
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//fetch:subselect 子查询 (select .. where id in (select ..)) (多表查询换成 单表查询和子查询,两次查询)
//lazy:false 立即加载
public void fun6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list(); // 查询所有的Customer(单表查询)。 同时立即查询关联的LinkMan对象(子查询)。(多表查询换成两次查询)
for(Customer c:list){
System.out.println(c);
System.out.println(c.getLinkMens().size());
System.out.println(c.getLinkMens());
}
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//fetch:subselect 子查询 (select .. where id in (select ..)) (多表查询换成 单表查询和子查询,两次查询)
//lazy:extra 极其懒惰。 和懒加载基本相同,只是在使用关联集合的size时有区别。
public void fun7(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list(); // 查询所有的Customer(单表查询)。 不会立即查询关联的LinkMan对象。
for(Customer c:list){
System.out.println(c);
System.out.println(c.getLinkMens().size()); // 只使用size时,只会"select count(id)..." (子查询)
System.out.println(c.getLinkMens()); // 使用LinkMan对象时,才会去加载完整的LinkMan。 (子查询)
}
//----------------------------------------------------
tx.commit();
session.close();
}
}
Customer.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="cn.xxx.domain" >
<class name="Customer" table="cst_customer" lazy="true" > <!-- lazy 类级别的懒加载(建议使用默认值"true") -->
<id name="cust_id" >
<generator class="native"></generator>
</id>
<property name="cust_name" column="cust_name" ></property>
<property name="cust_source" column="cust_source" ></property>
<property name="cust_industry" column="cust_industry" ></property>
<property name="cust_level" column="cust_level" ></property>
<property name="cust_linkman" column="cust_linkman" ></property>
<property name="cust_phone" column="cust_phone" ></property>
<property name="cust_mobile" column="cust_mobile" ></property>
<!--
一对多关系;一个Customer对象对多个LinkMan对象。(Customer和LinkMan互为关联对象)
lazy属性: 是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰。和懒加载基本相同,只是在使用集合的size时 不同。
fetch属性: 加载关联对象的策略.使用什么类型的sql语句加载集合数据(加载关联对象)
select(默认值): 单表查询加载
join: 使用多表查询加载关联对象(集合)
subselect:使用子查询加载关联对象(集合)
-->
<set name="linkMens" lazy="true" fetch="select" >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>
</class>
</hibernate-mapping>