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);
}
}
}
Hibernate —— 理解fetch抓取策略
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.