鷹翔宇空

          學習和生活

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks
          原文引自:http://www.gamvan.com/developer/java/opener/2005/7/527.html
          1.兩種配置文件: 
            A.hibernate.cfg.xml   和   B.hibernate.properties 
            A中可含映射文件的配置,而B中hard codes加映射文件。
            A。Configuration config=new Configuration().config(); 
            B. Configuration config=new Configuration(); 
               config.addClass(TUser.class); 

          2.你不必一定用hibernate.cfg.xml或hibernate.properties這兩文件名, 
             你也不一定非得把配置文件放在Classes下, 
             File file=new File("c:\\sample\\myhibernate.xml"); 
             Configuration config=new Configuration().config(file); 
          3. session.Flush() 
             強制數(shù)據(jù)庫立即同步,當用事務(wù)時,不必用flush,事務(wù)提交自動調(diào)用flush 
             在session關(guān)閉時也會調(diào)用flush 

          4. Hibernate總是使用對象類型作為字段類型 
          5. XDoclet專門建立了hibernate doclet,就是在java代碼上加上一些 
             java docTag,后來再讓XDoclet分析該java代碼,生成映射文件; 
          6.HQL子句本身大小寫無關(guān),但是其中出現(xiàn)的類名和屬性名必須注意大小寫區(qū)分。
          7.關(guān)系: 
            Constrained : 約束,表明主控表的主鍵上是否存在一個外鍵(foreigh key) 
             對其進行約束。 
            property-ref:關(guān)聯(lián)類中用于與主控類相關(guān)聯(lián)的屬性名,默認為關(guān)聯(lián)類的主鍵屬性名
            單向一對多需在一方配置,雙向一對多需在雙方進行配置
          8.lazy=false:被動方的記錄由hibernate負責記取,之后存放在主控方指定的 
            Collection類型屬性中 
          9. java.util.Set或net.sof.hibernate.collecton.Bag類型的Collection

          10.重要:inverse:用于標識雙向關(guān)聯(lián)中的被動方一端。 
                   inverse=false的一方(主控方)負責維護關(guān)聯(lián)關(guān)系.默認值:false 
          11.batch-size:采用延遲加載特征時,一次讀入的數(shù)據(jù)數(shù)昨。
          12.一對多通過主控方更新(主控方為一方時)
             user.getAddresses().add(addr); 
             session.save(user);//通過主控對象級聯(lián)更新   
          13.在one-to-many 關(guān)系中,將many 一方設(shè)為主動方(inverse=false)將有助性能 
             的改善。在一方設(shè)置關(guān)系時,inverse=true,即將主控權(quán)交給多方, 
             這樣多方可主動從一方獲得foreign key,然后一次insert即可完工。 

             addr.setUser(user);//設(shè)置關(guān)聯(lián)的TUser對象 
             user.getAddresses().add(addr); 
             session.save(user);//級聯(lián)更新  
          14.只有設(shè)為主控方的一方才關(guān)心(訪問)對方的屬性,被動方是不關(guān)心對方的屬性的。
          15.one-to-many與many-to-one節(jié)點的配置屬性不同: 
             一對多關(guān)系多了lazy和inverse兩個屬性 
             多對多節(jié)點屬性:column:中間映射表中,關(guān)聯(lián)目標表的關(guān)聯(lián)字段 
                             class:類名,關(guān)聯(lián)目標類 
                             outer-join:是否使用外聯(lián)接     
             注意:access是設(shè)置屬性值的讀取方式。

                  column是設(shè)置關(guān)聯(lián)字段。 

          16.多對多,注意兩方都要設(shè)置inverse和lazy,cascade只能設(shè)為insert-update 
             多對多關(guān)系中,由于關(guān)聯(lián)關(guān)系是兩張表相互引用,因此在保存關(guān)系狀態(tài)時必須對雙方同時保存。 
             group1.getRoles().add(role1); 
             role1.getGroups().add(group1); 
             session.save(role1); 
             session.save(group1); 
          17.關(guān)于vo和po 
             vo經(jīng)過hibernate容量處理,就變成了po(該vo的引用將被容器保存,并且在session關(guān)閉時flush,因此po如果再傳到其它地方改變了,就危險了) 
            
             vo和po相互轉(zhuǎn)換:BeanUtils.copyProperties(anotherUser,user); 
          18.對于save操作而言,如果對象已經(jīng)與Session相關(guān)聯(lián)(即已經(jīng)被加入Session的實體容器中),則無需進行具體的操作。因為之后的Session.flush過程中,Hibernate 
          會對此實體容器中的對象進行遍歷,查找出發(fā)生變化的實體,生成并執(zhí)行相應(yīng)的update 
          語句。 
          19.如果我們采用了延遲加載機制,但希望在一些情況下,實現(xiàn)非延遲加 
          載時的功能,也就是說,我們希望在Session關(guān)閉后,依然允許操作user的addresses 
          屬性 
          Hibernate.initialize方法可以通過強制加載關(guān)聯(lián)對象實現(xiàn)這一功能: 
          這也正是我們?yōu)槭裁丛诰帉慞OJO時,必須用JDK Collection接口(如Set,Map), 
          而非特定的JDK Collection實現(xiàn)類(如HashSet、HashMap)申明Collection屬性的 
          原因。 
          20.事務(wù):從sessionFactory獲得session,其自動提交屬性就已經(jīng)關(guān)閉(AutoCommit=false),此時若執(zhí)行了jdbc操作,如果不顯式調(diào)用session.BeginTransaction(),是不會執(zhí)行事務(wù)操作的。
             jdbc transaction:基于同一個session(就是同一個connection)的事務(wù); 
             jta  transaction:跨session(跨connection)事務(wù). 
             對于jta事務(wù),有三種實現(xiàn)方法: 
               A。UserTransaction tx=new InitialContext().lookup("..."); 
                  tx.commit(); 
               B. 使用hibernate封裝的方法:(不推薦) 
                  Transaction tx=session.beginTransaction(); 
                  tx.commit(); 
               C. 使用ejb之sessionBean的事務(wù)技持方法,你只要在把需要在發(fā)布描述符中,把需要jta事務(wù)的方法聲明為require即可 
          21.悲觀鎖,樂觀鎖: 
             樂觀鎖一般通過version來實現(xiàn),注意version節(jié)點必須出現(xiàn)在id后。 

          22.Hibernate中,可以通過Criteria.setFirstResult和Criteria.setFetchSize方法設(shè)定分頁范圍。 
             Query接口中也提供了與其一致的方法,hibernate主要在dialect類中實現(xiàn)在這個功能。 

          23.cache 
             <hibernate-configuration> 
           <session-factory> 
           …… 
            <property name="hibernate.cache.provider_class"> 
             net.sf.ehcache.hibernate.Provider 
            </property>  
            還需對ecache本身進配置 
            <ehcache> 
           <diskStore path="java.io.tmpdir"/> 
           <defaultCache 
           maxElementsInMemory="10000" //Cache中最大允許保存的數(shù)據(jù)數(shù)量 
           eternal="false" //Cache中數(shù)據(jù)是否為常量 
           timeToIdleSeconds="120" //緩存數(shù)據(jù)鈍化時間 
           timeToLiveSeconds="120" //緩存數(shù)據(jù)的生存時間 
           overflowToDisk="true" //內(nèi)存不足時,是否啟用磁盤緩存 
           /> 
            </ehcache> 
            之后在映射文件中指定各個映射實體的cache策略 
            <class name=" org.hibernate.sample.TUser" .... > 
           <cache usage="read-write"/> 
           .... 
           <set name="addresses" .... > 
            <cache usage="read-only"/> 
           .... 
           </set> 
           </class> 
          Query.list()跟Query.iterate()的不同: 
           對于query.list()總是通過一條sql語句獲取所有記錄,然后將其讀出,填入pojo返回; 
           但是query.iterate(),則是首先通過一條Select SQL 獲取所有符合查詢條件的記錄的 
          id,再對這個id 集合進行循環(huán)操作,通過單獨的Select SQL 取出每個id 所對應(yīng)的記 
          錄,之后填入POJO中返回。 
           也就是說,對于list 操作,需要一條SQL 完成。而對于iterate 操作,需要n+1 
          條SQL。,list方法將不會從Cache中讀取數(shù)據(jù)。iterator卻會。 

          24.ThreadLocal:它會為每個線程維護一個私有的變量空間。實際上, 
          其實現(xiàn)原理是在JVM 中維護一個Map,這個Map的key 就是當前的線程對象,而value則是 
          線程通過ThreadLocal.set方法保存的對象實例。當線程調(diào)用ThreadLocal.get方法時, 
          ThreadLocal會根據(jù)當前線程對象的引用,取出Map中對應(yīng)的對象返回。 
           這樣,ThreadLocal通過以各個線程對象的引用作為區(qū)分,從而將不同線程的變量隔離開 
          來。 

          25.Hibernate官方開發(fā)手冊標準示例: 
            public class HibernateUtil { 
          private static SessionFactory sessionFactory; 
          static { 
          try { 
          // Create the SessionFactory 
          sessionFactory = new 
          Configuration().configure().buildSessionFactory(); 
          } catch (HibernateException ex) { 
          throw new RuntimeException( 
          "Configuration problem: " + ex.getMessage(), 
          ex 
          ); 


          public static final ThreadLocal session = new ThreadLocal(); 
          public static Session currentSession() throws HibernateException 

          Session s = (Session) session.get(); 
          // Open a new Session, if this Thread has none yet 
          if (s == null) { 
          s = sessionFactory.openSession(); 
          session.set(s); 

          return s; 

          public static void closeSession() throws HibernateException { 
          Session s = (Session) session.get(); 
          session.set(null); 
          if (s != null) 
          s.close(); 

          }  

               
          26.通過filter實現(xiàn)session的重用: 
             public class PersistenceFilter implements Filter 

          protected static ThreadLocal hibernateHolder = new ThreadLocal(); 
          public void doFilter(ServletRequest request, ServletResponse 
          response, FilterChain chain) 
          throws IOException, ServletException 

          hibernateHolder.set(getSession()); 
          try 

          …… 
          chain.doFilter(request, response); 
          …… 

          finally 

          Session sess = (Session)hibernateHolder.get(); 
          if (sess != null) 

          hibernateHolder.set(null); 
          try 

          sess.close(); 

          catch (HibernateException ex) { 
          throw new ServletException(ex); 




          ……} 
          27.Spring的參數(shù)化事務(wù)管理功能相當強大,筆者建議在基于Spring Framework的應(yīng)用 
          開發(fā)中,盡量使用容器管理事務(wù),以獲得數(shù)據(jù)邏輯代碼的最佳可讀性。 
            
          public class UserDAO extends HibernateDaoSupport implements IUserDAO 

          public void insertUser(User user) { 
          getHibernateTemplate().saveOrUpdate(user); 



            上面的UserDAO實現(xiàn)了自定義的IUserDAO接口,并擴展了抽象類: 
          HibernateDaoSupport 
          HibernateSupport實現(xiàn)了HibernateTemplate和SessionFactory實例的關(guān)聯(lián)。 
          HibernateTemplate對Hibernate Session操作進行了封裝,而 
          HibernateTemplate.execute方法則是一封裝機制的核心 
            *在spring的配置文件里,移植了整個hibernate.cfg.xml的內(nèi)容。
          posted on 2006-02-20 14:37 TrampEagle 閱讀(337) 評論(0)  編輯  收藏 所屬分類: 技術(shù)文摘
          主站蜘蛛池模板: 酉阳| 枞阳县| 太白县| 绵阳市| 固安县| 济南市| 长海县| 邮箱| 宽城| 安岳县| 贵港市| 聊城市| 河源市| 石城县| 承德市| 林周县| 扬州市| 江源县| 万山特区| 随州市| 阿图什市| 龙泉市| 贵港市| 太保市| 寿光市| 曲靖市| 兴安盟| 漳浦县| 泸西县| 礼泉县| 南开区| 塔河县| 徐闻县| 合阳县| 开阳县| 西充县| 商水县| 上饶市| 五大连池市| 韶山市| 汨罗市|