posts - 66,  comments - 11,  trackbacks - 0
          package com.hibernate.higherApplication;

          import java.util.Iterator;
          import java.util.List;
          import java.util.Set;

          import junit.framework.TestCase;

          import org.hibernate.Criteria;
          import org.hibernate.Hibernate;
          import org.hibernate.HibernateException;
          import org.hibernate.Query;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;
          import org.hibernate.criterion.Expression;

          public class DurationOperator extends TestCase {
              
          private SessionFactory sessionFactory = null;
              
          private Session session = null;
              
          /**
               * 初始化資源
               
          */
              
          protected void setUp() throws Exception {
                  
          try {
                      
          //加載類路徑下的hibernate.cfg.xml文件
                      Configuration config = new Configuration().configure();
                      
          //創建sessionFactory對象
                      sessionFactory = config.buildSessionFactory();
                      
          //創建session
                      session = sessionFactory.openSession();
                  } 
          catch (HibernateException e) {
                      e.printStackTrace();
                  }
              }
              
          /**
               * load/get方法均可以根據指定的實體類和id從數據庫讀取記錄,并返回與之對應的實體對象。
               * 區別在于:
               * 1、如果未發現符合條件的記錄,get方法返回null,而load方法拋出一個ObjectNotFoundException
               * 2、load方法可以返回實體的代理類實例,而get方法永遠直接返回實體類。
               * 3、load方法可以充分利用內部緩存和二級緩存中的現有數據,而get方法則僅僅在內部緩存中進行數據查找,如果
               * 沒有發現數據,將越過二級緩存,直接調用SQL完成數據讀取。
               *
               
          */
              
          public void loadOrGetData(){
                  TUser user 
          = (TUser)session.load(TUser.class,new Integer(1));
              }
              
          /**
               * 查詢性能往往是一系統性能表現的一個重要方面。
               * query.list方法通過一條select SQL實現了查詢操作,而iterate方法,則執行了3次selectSQL,第一次獲取了所有符合條件的記錄
               * 的id,之后,在根據各個id從庫表中讀取對應的哦記錄,這是一個典型的N+1次查詢問題。
               * 
               * 我們進行query.list數據查詢時,即使緩存中已經有一些符合條件的實體對象存在,我們也無法保證這些數據就是庫表中所有符合條件的數據。假設
               * 第一次查詢條件是age>25,隨即緩存中就包括了所有age>25的user數據;第二次查詢條件為age>20,此時緩存中雖然包含了滿足age>25d的
               * 數據,但這些并不是滿足條件age>20的全部數據
               * 因此,query.list方法還是需要執行一次select sql以保證查詢結果的完整性(iterate方法通過首先查詢獲取所有符合條件記錄的id,以此保證
               * 查詢結果的完整性)。
               * 因此,query.list方法實際上無法利用緩存,它對緩存只寫不讀。而iterate方法則可以充分發揮緩存帶來的優勢,如果目標數據只讀或者讀取相對
               * 較為頻繁,通過這種機制可以大大減少性能上的損耗。
               
          */
              
          public void queryForList(){
                  String hql 
          = "from TUser where age>?";
                  Query query 
          = session.createQuery(hql);
                  query.setInteger(
          1,1);
                  
                  List list 
          = query.list();
                  
                  
          for(int i=0;i<list.size();i++){
                      TUser user 
          = (TUser)list.get(i);
                      System.out.println(
          "User age:"+user.getAge());
                  }
              }
              
          public void queryForIterate(){
                  String hql 
          = "from TUser where age>?";
                  Query query 
          = session.createQuery(hql);
                  query.setInteger(
          1,1);
                  
                  Iterator it 
          = query.iterate();
                  
                  
          while(it.hasNext()){
                      TUser user 
          = (TUser)it.next();
                      System.out.println(
          "User age:"+user.getAge());
                  }
              }
              
          /**
               * 大數據量的批量讀取(10W條)
               * 解決方案:結合iterate方法和evict方法逐條對記錄進行處理,將內存消耗保持在可以接受的范圍之內。
               * 在實際開發中,對于大批量數據處理,還是推薦采用SQL或存儲過程實現,以獲得較高的性能,并保證系統平滑運行。
               
          */
              
          public void bigDataRead(){
                  String hql 
          = "from TUser where age>?";
                  Query query 
          = session.createQuery(hql);
                  query.setInteger(
          "age"1);
                  Iterator it 
          = query.iterate();
                  
                  
          while(it.hasNext()){
                      TUser user 
          = (TUser)it.next();
                      
          //將對象從一級緩存中移除
                      session.evict(user);
                      
          //二級緩存可以設定最大數據緩存數量,達到峰值時會自動對緩存中的較老數據進行廢除,但是我們這里還是通過
                      
          //編碼指定將對象從二級緩存中移除,這有助保持緩存的數據有效性。
                      sessionFactory.evict(TUser.class,user.getId());
                  }
              }
              
          /**
               * Query Cache彌補了find方法的不足,QueryCache中緩存的SQL及其結果及并非永遠存在,當Hibernate發現此SQL對應的庫表發生變動,
               * 會自動將Query Cache中對應表的SQL緩存廢除。因此Query Cache只在特定的情況下產生作用:
               * 1、完全相同的select SQL重復執行。
               * 2、在2次查詢之間,此select SQL對應的庫表沒有發生過改變。
               
          */
              
          public void queryForQueryCache(){
                  String hql 
          = "from TUser where age>?";
                  Query query 
          = session.createQuery(hql);
                  query.setInteger(
          11);
                  
          //除了在這里設置QueryCache外,還要在hibernate.cfg.xml中進行設置
                  
          //<property name="hibernate.cache.use_query_cache">true</property>
                  query.setCacheable(true);
                  List userList 
          = query.list();
              }
              
          /**
               * 所謂延遲加載,就是在需要數據的時候,才真正執行數據加載操作。
               * 延遲加載實現主要針對:
               * 1、實體對象:通過class的lazy屬性,我們可以打開實體對象的延遲加載功能。
               * 2、集合
               
          */
              
          public void queryForEntityLazy(){
                  Criteria criteria 
          = session.createCriteria(TUser.class);
                  criteria.add(Expression.eq(
          "name","Erica"));
                  
                  List userList 
          = criteria.list();
                  TUser user 
          = (TUser)userList.get(0);
                  
          //雖然使用了延遲加載,但是我們可以通過hibernate的初始化方法進行強制加載,這樣即使session關閉之后,關聯的對象仍讓可以使用
                  Hibernate.initialize(user.getAddresses());
                  
                  System.out.println(
          "User name=>"+user.getAge());
                  
                  Set hset 
          =user.getAddresses();
                  TAddresses addr 
          = (TAddresses)hset.toArray()[0];
                  System.out.println(addr.getAddress());
                  
                  session.close();
              }
              
          /**
               * 關閉資源
               
          */
              
          protected void tearDown() throws Exception {
                  
          try{
                      session.close();
                  }
          catch(HibernateException e){
                      e.printStackTrace();
                  }
              }

          }
          posted on 2010-01-02 15:27 王永慶 閱讀(367) 評論(0)  編輯  收藏 所屬分類: HIBERNATE
          <2010年1月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關注blogs

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 英山县| 哈巴河县| 宜阳县| 伊川县| 施甸县| 乳山市| 青州市| 沂南县| 阿鲁科尔沁旗| 扎囊县| 平舆县| 资中县| 巴塘县| 滕州市| 青冈县| 且末县| 上林县| 新河县| 全州县| 桓仁| 铅山县| 洛隆县| 娱乐| 南平市| 惠州市| 疏勒县| 密山市| 静宁县| 交城县| 富锦市| 邹平县| 炉霍县| 腾冲县| 札达县| 册亨县| 平武县| 玉山县| 准格尔旗| 金昌市| 大方县| 尚志市|