您的位置:首页 > Web前端

Hibernate —— 理解fetch抓取策略

2016-04-15 14:07 363 查看
package me.ljm.hibernate.test;

import java.util.List;

import me.ljm.hibernate.entity.Classroom;
import me.ljm.hibernate.entity.Student;

import org.hibernate.Session;
import org.junit.Test;

/**
* 抓取策略测试
* @author ljm
*
*/
public class FetchTest extends AbstractTest {

/**
* 条件:
* 此时为xml的测试默认情况:fetch=select
* 我们来加载一个对象,且不导航关联对象
*
* 结果:
* 一条语句,没有关联查询
* select student0_.id as id2_0_, student0_.name as name2_0_, student0_.sex as sex2_0_,
*        student0_.cla_id as cla4_2_0_ from t_student student0_ where student0_.id=?
* @throws Exception
*/
@Test
public void testSelectOnLoadAndNoNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName());

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的另一种情况:fetch=join
* 我们来加载一个对象,且不导航关联对象
*
* 结果:
* 一条SQL,关联查询
* select student0_.id as id2_2_, student0_.name as name2_2_, student0_.sex as sex2_2_,
*        student0_.cla_id as cla4_2_2_, classroom1_.id as id1_0_, classroom1_.name as name1_0_,
*        classroom1_.grade as grade1_0_, classroom1_.special_id as special4_1_0_,
*        special2_.id as id0_1_, special2_.name as name0_1_, special2_.type as type0_1_
*  from t_student student0_
*  left outer join t_classroom classroom1_ on student0_.cla_id=classroom1_.id
*  left outer join t_special special2_ on classroom1_.special_id=special2_.id
*   where student0_.id=?
* @throws Exception
*/
@Test
public void testJoinOnLoadAndNoNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName());

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的测试默认情况:fetch=select
* 我们来加载一个对象 ,导航关联对象
*
* 结果:
* 发出3条SQL语句,不关联查询
* Hibernate: select student0_.id as id2_0_, student0_.name as name2_0_,
*                   student0_.sex as sex2_0_, student0_.cla_id as cla4_2_0_
*              from t_student student0_ where student0_.id=?
* Hibernate: select classroom0_.id as id1_0_, classroom0_.name as name1_0_,
*                   classroom0_.grade as grade1_0_, classroom0_.special_id as special4_1_0_
*              from t_classroom classroom0_ where classroom0_.id=?
* Hibernate: select special0_.id as id0_0_, special0_.name as name0_0_,
*                   special0_.type as type0_0_
*              from t_special special0_ where special0_.id=?
* 陈虎,计算机教育1班,计算机教育
* @throws Exception
*/
@Test
public void testSelectOnLoadAndNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName()+","+stu.getClassroom().getName()
+","+stu.getClassroom().getSpecial().getName());

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的另一种情况:fetch=join
* 我们来加载一个对象,导航关联对象
*
* 结果:
* 发出一条SQL,关联查询
* Hibernate: select student0_.id as id2_2_, student0_.name as name2_2_, student0_.sex as sex2_2_,
*                   student0_.cla_id as cla4_2_2_, classroom1_.id as id1_0_,
*                   classroom1_.name as name1_0_, classroom1_.grade as grade1_0_,
*                   classroom1_.special_id as special4_1_0_, special2_.id as id0_1_,
*                   special2_.name as name0_1_, special2_.type as type0_1_
*              from t_student student0_
*                   left outer join t_classroom classroom1_ on student0_.cla_id=classroom1_.id
*                   left outer join t_special special2_ on classroom1_.special_id=special2_.id
*             where student0_.id=?
* 陈虎,计算机教育1班,计算机教育
* @throws Exception
*/
@Test
public void testJoinOnLoadAndNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName()+","+stu.getClassroom().getName()
+","+stu.getClassroom().getSpecial().getName());

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的测试默认情况:fetch=select
* 我们来列出所有对象 ,不导航关联对象
*
* 结果:
* 一条SQL,不关联查询
* Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.sex as sex2_,
*                   student0_.cla_id as cla4_2_ from t_student student0_
* @throws Exception
*/
@Test
public void testSelectOnListAndNoNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

List<Student> stus = session.createQuery("from Student").list();
for (Student stu : stus) {
System.out.println(stu.getName());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的另一种情况:fetch=join
* 我们来列出所有对象 ,不导航关联对象
*
* 结果:
* 1条SQL,不关联查询
* Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.sex as sex2_,
*                   student0_.cla_id as cla4_2_ from t_student student0_
* @throws Exception
*/
@Test
public void testJoinOnListAndNoNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

List<Student> stus = session.createQuery("from Student").list();
for (Student stu : stus) {
System.out.println(stu.getName());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的测试默认情况:fetch=select
* 我们来列出所有对象 ,导航关联对象
*
* 结果:
* 发出大量的SQL,延迟加载导致
* Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.sex as sex2_,
*                   student0_.cla_id as cla4_2_
*              from t_student student0_ limit ?
* Hibernate: select classroom0_.id as id1_0_, classroom0_.name as name1_0_,
*                   classroom0_.grade as grade1_0_, classroom0_.special_id as special4_1_0_
*              from t_classroom classroom0_ where classroom0_.id=?
* Hibernate: select special0_.id as id0_0_, special0_.name as name0_0_,
*                   special0_.type as type0_0_
*              from t_special special0_ where special0_.id=?
*
* Hibernate: select classroom0_.id as id1_0_, classroom0_.name as name1_0_,
*                   classroom0_.grade as grade1_0_, classroom0_.special_id as special4_1_0_
*              from t_classroom classroom0_ where classroom0_.id=?
*              .....
*              .....
*              .....
* @throws Exception
*/
@Test
public void testSelectOnListAndNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

List<Student> stus = session.createQuery("from Student")
.setFirstResult(0).setMaxResults(200).list();
for (Student stu : stus) {
System.out.println(stu.getName()+","+stu.getClassroom()
+","+stu.getClassroom().getSpecial());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 条件:
* 此时为xml的另一种情况:fetch=join
* 我们来列出所有对象 ,导航关联对象
*
* 结果:
* 发出大量的SQL,延迟加载导致;
* 和fetch=select不同的是,导航的第一个对象会延迟加载,导航的第二个对象会关联加载。所以相对来说SQL语句的数量少一些。
*
* 结论:
* fetch=join作用:
* 1、在xml配置的情况中,
*    如果只得到Student列表,则和fetch=select的效果一样;解决方法是bitch-size 和 join fetch
*    如果要得到Student关联的Classroom,则会取出所有关联的对象,即使并未用到Special
* fetch=FetchType.EARGER(相当于fetch=join):
* 1、在annotation配置的情况下,
*    会取出所有的关联对象
* Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.sex as sex2_,
*                   student0_.cla_id as cla4_2_
*              from t_student student0_ limit ?
* Hibernate: select classroom0_.id as id1_1_, classroom0_.name as name1_1_,
*                   classroom0_.grade as grade1_1_, classroom0_.special_id as special4_1_1_,
*                   special1_.id as id0_0_, special1_.name as name0_0_,
*                   special1_.type as type0_0_
*              from t_classroom classroom0_
*                   left outer join t_special special1_ on classroom0_.special_id=special1_.id
*             where classroom0_.id=?
*
* Hibernate: select classroom0_.id as id1_1_, classroom0_.name as name1_1_,
*                   classroom0_.grade as grade1_1_, classroom0_.special_id as special4_1_1_,
*                   special1_.id as id0_0_, special1_.name as name0_0_,
*                   special1_.type as type0_0_
*              from t_classroom classroom0_
*                   left outer join t_special special1_ on classroom0_.special_id=special1_.id
*             lwhere classroom0_.id=?
*              .....
*              .....
*              .....
* @throws Exception
*/
@Test
public void testJoinOnListAndNav() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

/*List<Student> stus = session.createQuery("from Student")
.setFirstResult(0).setMaxResults(200).list();
for (Student stu : stus) {
System.out.println(stu.getName()+","+stu.getClassroom()
+","+stu.getClassroom().getSpecial());
}*/
List<Classroom> clas = session.createQuery("from Classroom").list();
for (Classroom classroom : clas) {
System.out.println(classroom.getName()+","+classroom.getSpecial());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

@Test
public void testFetchEqualsLazy() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

List<Student> stus = session.createQuery("select stu from Student stu join stu.classroom").list();
for (Student stu : stus) {
System.out.println(stu.getName()+","+stu.getClassroom());
//				System.out.println(stu.getName());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}

/**
* 发出多条sql的最佳解决方案
* join fetch
* 但join fetch不能使用 select count(*)
* @throws Exception
*/
@Test
public void testFetchSolution() throws Exception {
Session session = null;
try {
session = getSession();
session.beginTransaction();

List<Student> stus = session.createQuery("select stu from Student stu left join fetch stu.classroom").list();
for (Student stu : stus) {
System.out.println(stu.getName()+","+stu.getClassroom());
}

session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
e.printStackTrace();
} finally {
close(session);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: