懶加載測試:
/*類的延遲加載
* * session.get * 1、方法加載出來的對象是class對象 * 2、在session.get方法執行的時候發出sql語句 * 3、class對象是有值的 * session.load * 1、方法加載出來的對象是class的代理對象 * 2、在加載其屬性的時候發出sql語句(按照需求加載,延遲加載) * 3、獲取標識符屬性是不用延遲加載的,獲取普通屬性是需要發出sql語句的 * 標識符屬性對於延遲加載不起作用 */ 映射文件: Class.hbm.xml 實體類: Class Hibernate類的延遲加載測試: Configuration configuration = new Configuration(); configuration.configure("com/hibernate/lazy/hibernate.cfg.xml"); sessionFactory = configuration.buildSessionFactory(); ClassLazyTest: session.get(CLass.class,1L); session.close(); session.load(CLass.class,1L); session.close(); /* * session.get * 1、方法加載出來的對象是class對象 * 2、在session.get方法執行的時候發出sql語句 * 3、class對象是有值的 session.load * 1、方法加載出來的對象是class的代理對象 * 2、在加載其屬性的時候發出sql語句(按照需求加載,延遲加載) * 3、獲取標識符屬性是不用延遲加載的,獲取普通屬性是需要發出sql語句的標識符屬性對於延遲加載不起作用 */ ReferenceRelationTest: Class user =(Class)session.get(Class.class,1L); Set<Student> student = user.getStudents(); for(Student stu : student) { System.out.println(stu.getName()); } seesion.close(); 深入: /* * 當集合的lazy為true時 * Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.cid as cid1_0_ from student students0_ where students0_.cid=? * 當集合的lazy為extra時 extra為更進一步的延遲加載 * Hibernate: select count(sid) from student where cid =? */
那什么時候使用懶加載? 處理大數據量時,為了減少對數據庫的查詢次數和對數據的取舍(有些沒用到的關聯數據夜查出來了),這時候就應當使用它。
抓取策略:
部分代碼測試貼上:
/* * 抓取策略 * 例子:在加載class的時候怎么樣去加載student * 應用范圍:在加載一端對象的時候,去加載多的一端對象的時候的方式 * 抓取策略和延遲加載----->研究對象是集合,這一點應該不難理解,懶加載是在一對多/多對多關聯中,從的一方拿數據是否延遲加載多的那方。 抓取策略則是操作者本身已經明確了需要獲取哪些數據,並且是在關聯關系簡單生成的SQL語句卻很多,針對的也是一對多/多對多的關系 * lazy fetch * false select 有作用 * true join 延遲加載失效 * false subselect 有作用 * * 總結:當fetch為join時,延遲加載失去作用 * 當fetch為select時或者為subselect時,延遲加載能控制sql語句的發出時間 * */ public class FetchTest { private static SessionFactory sessionFactory = null; static { Configuration configuration = new Configuration(); configuration.configure("cn/heima5/hibernate/fetch/hibernate.cfg.xml"); sessionFactory = configuration.buildSessionFactory(); } /* * 先查詢所有的class數據,再根據class查詢student,其本身的查詢符合子查詢 * 所以在這個例子中,可以用fetch="subselect"提高效率 1、如果用fetch="select"將導致n+1次查詢 * n代表class表中的行數 2、用fetch="join"不起作用 * 3、應用fetch="subselect"或者fetch="select"與batch-size結合起來使用 */ @Test public void testQuery() { Session session = sessionFactory.openSession(); List<Class> classList = session.createQuery("from Class").list(); for (Class class1 : classList) { Set<Student> students = class1.getStudents(); for (Student student : students) { System.out.println(student.getSname()); } } session.close(); } /* * 說明 * 1、如果fetch="select"發出兩條sql語句 * 第一條查詢給定的ID的值的class對象 * 第二條查詢根據cid查詢student * 2、如果fetch="join",發出一條sql語句 左外連接 */ @Test public void testQuery2() { Session session = sessionFactory.openSession(); Class class1 = (Class)session.get(Class.class, 1L); Set<Student> students = class1.getStudents(); for (Student student : students) { System.out.println(student.getSname()); } session.close(); } /* * 通過分析屬於子查詢的內容,所以抓取策略為fecth="subselect" */ @Test public void testQuery3(){ Session session = sessionFactory.openSession(); List<Class> classList = session.createQuery("from Class where cid in(1,2,3,5,7)").list(); for (Class class1 : classList) { Set<Student> students = class1.getStudents(); for (Student student : students) { System.out.println(student.getSname()); } } session.close(); }
總結:當fetch為join時,延遲加載失去作用
當fetch為select時或者為subselect時,延遲加載能控制sql語句的發出時間
Session緩存:
后續更新