無線&移動互聯網技術研發

          換位思考·····
          posts - 19, comments - 53, trackbacks - 0, articles - 283
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Hibernate 主要知識點的歸納

          Posted on 2010-05-27 01:11 Gavin.lee 閱讀(1330) 評論(0)  編輯  收藏 所屬分類: SSH2 --Hibernate
           

          一、HibernateORMObject Relation Mapping)對象關系映射框架

          常用的ORM框架有:HibernateTopLinkOJB

          Hibernate 框架完全是進行對象的操作,不再會有對字段、屬性的操作。如Hibernate 刪除則是刪除一個對象,更新則是對某一個對象狀態進行更新

          小貼士:應用Hibernate開發時,可與JDBC相聯想

          二、開發流程:

          1.Domain Object ----mapping -----db(官方推薦)

          2.DB開始,用工具生成mappingDomain Object(使用較多)

          3.由映射文件開始

          Domain Object 限制:

          1.默認的構造方法(必須的)

          2.有無意義的標示符id(主鍵)(可選)

          3.final,對懶加載有影響

          三、需要一個工具類,只加載一次 hibernate.cfg.xml 文件

          package cn.itcast.hibernate;

          import org.hibernate.Session;

          import org.hibernate.SessionFactory;

          import org.hibernate.cfg.Configuration;

          publicfinalclass HibernateUtil 
          {

              
          private HibernateUtil() {}

              privatestatic SessionFactory sf 
          = null

              
          static {

                  Configuration cfg 
          = new Configuration();

                  cfg.configure();

          //cfg.configure(new File("filename")); //指定配置文件的路徑,不指定則默認

                  sf 
          = cfg.buildSessionFactory();

              }
             

              publicstatic SessionFactory getSessionFactory() 
          {

                  returnsf;

              }
             

              publicstatic Session getSession() 
          {

                  returnsf.openSession();

              }


          }

           

          小貼士:將java類與hibernate源碼綁定

          四、Mysql 有多種引擎:

              MyISAM:5.0以前的缺省引擎,效率高但不支持事務。

              InnoDB:支持事務,則Hibernate操作時需要開啟事務,進行操作后提交事務,這樣才能將數據持久化:

          Transaction tx = s.beginTransaction();//開啟事務

                  User user = new User();

                  user.setName("name");

                  user.setBirthday(new Date());

                  s.save(user);

          tx.commit(); //事務提交

          五、Hibernate 核心接口概述:

          Configuration:

          負責管理Hibernate的配置信息,這些信息由配置文件提供,包括如下內容:

          1.Hibernate運行的底層信息:數據庫的URL、用戶名、密碼、JDBC驅動類等,數據庫Dialect,數據庫連接池等。

          2.Hibernate映射文件(*.hbm.xml

          調用代碼:

          1.屬性文件(hibernate.properties)

          Configuration cfg = new Configuration();

          cfg.addClass(XXX.class);//該方法加載XXX.hbm.xml

          cfg.addResource();

          2.XML文件(hibernate.cfg.xml

          Configuration cfg = new Configuration();

          cfg.configure();

          SessionFactory:

          1.應用程序從SessionFactory(會話工廠)里獲得Session(會話)實例。它在多個應用線程間進行共享。通常情況下,整個應用只有唯一的一個會話工廠---例如在應用初始化時被創建。然而,如果你使用Hibernate訪問多個數據庫,你需要每個數據庫使用一個會話工廠。

          2.會話工廠緩存了生成的SQL語句和Hibernate在運行時使用的映射元數據。

          3.調用代碼:

          privatestatic SessionFactory sf = null

          static {

              Configuration cfg = new Configuration();

              cfg.configure();

              sf = cfg.buildSessionFactory();

          }

          Session

          1.Session不是線程安全的,它代表與數據庫之間的一次操作會話

          2.Session也稱為持久化管理器,因為它是與持久化有關的操作接口

          3.Session通過SessionFactory打開,在所有的工作完成后,需要關閉

          4.Session緩存其管理的持久化對象

          5.調用代碼:

          Session session sessionFactory.openSession();

          Transaction:

          1.它將應用代碼從底層的事務實現中抽象出來---這可能是一個JDBC事務,一個JTA用戶事務或者甚至是一個公共對象請求代碼結構(CORBA---允許應用通過一組一致的API控制事務邊界

          2.這有助于保持Hibernate應用在不同類型的執行環境或容器中的可移植性

          3.Hibernate提供的事務提交模式默認為非自動提交模式(默認:autoCommit=false),因此使用Hibernate進行操作時(增、刪、改)必須顯示的調用TransactionAPI

          4.調用代碼:

          Transaction tx = session.beginTransction();

          Tx.commit()/rollback();

          Query/Criteria:

          1.Query接口封裝了Hibernate強大的對象查詢能力,同時也支持數據庫的更新操作

          2.提供了動態查詢的參數綁定功能

          3.提供list(),iterator(),scroll()等對象導航方法

          4.提供uiqueResult()方法獲取單獨的對象

          5.提供executeUpdate()方法來執行DML語句

          6.提供了可移植的分頁查詢方法

          Session

          1、savepresist保存數據,persist在事務外不會產生insert語句。

          2、delete,刪除對象

          3、update,更新對象,如果數據庫中沒有記錄,會出現異常,脫管對象如屬性改變需要保存,則調用update方法

          4、get,根據ID查,會立刻訪問數據庫

          5、load,根據ID查,(返回的是代理,不會立即訪問數據庫)

          6、saveOrUpdate,merge(根據IDversion的值來確定是否是saveupdate),調用merge你的對象還是托管的。當不知該對象的狀態時可調用該方法

          小貼士:瞬時對象id無值,脫管對象有值,hibernate通過該方式判斷對象的狀態

          7、lock(把對象變成持久對象,但不會同步對象的狀態)

          六、Hibernate中對象的狀態:

          狀態的參考:數據庫中是否有記錄;是否有session關聯

          1、瞬時(transient):數據庫中沒有數據與之對應,超過作用域被JVM垃圾回收器回收,一般是new出來且session沒有關聯的對象

          2、持久(persistent):數據庫中有數據與之對應,當前session有關聯,并且相關聯的session沒有關閉,事務沒有提交;持久對象狀態發生改變,在事務提交時會影響到數據庫(hibernate能檢測到)

          3、脫管(detached):數據庫中有數據與之對應,但當前沒有session與之關聯;托管對象狀態發生改變,hibernate不能檢測到

          對象在的狀態轉化:
              



          當對象被
          savecommit后,Hibernate Session 任然能察覺到對象,如果此時對象屬性發生改變,則數據庫中持久化的值同樣被改變,如:

              //標準方法

              static void addUser(User user) {

                  Session s = null;

                  Transaction tx = null;

                  try {

                      s = HibernateUtil.getSession();

                      tx = s.beginTransaction();

                      s.save(user);

          user.setName("new name");

                      tx.commit();

                  } catch (HibernateException e) {

                      if (tx != null) {

                          tx.rollback();

                      }

                      throw e;

                  } finally {

                      if (s != null)

                          s.close();

                  }

          }

          user對象在數據庫中最終持久化的name=="new name",如果在commit之前修改過的屬性,將會在commit時候統一對對象進行update

          七、Hibernate Query LanguageHQL)和CriteriaQBC

          HQL:面向對象的查詢語言,與SQL不同,HQL中的對象名是區分大小寫的(除了JAVA類和屬性其他部分不區分大小寫);HQL中查的是對象而不是和表,并且支持多態HQL主要通過Query來操作,Query的創建方式:

          Query q = session.createQuery(hql);

          1.from Person

          2.from User user where user.name=:name

          3.from User user where user.name=:name and user.birthday<:birthday

          static void query(String name) {

                  Session s = null;

                  try {

                      s = HibernateUtil.getSession();

                      String hql = "from User as user where user.name=?"//from Object ... 因為HQL支持多態,所以執行 from Object時,將會將所有的表都查一遍

                      /**

                       * 當查詢條件有多個的時候,則參數 "?" 將會有多個,這樣對我們的維護帶來極大不便,在HQL中我們利用命名參數處理

                       * "from User as user where user.name=?" -->> "from User as user where user.name=:n"

                       * query.setString("n", name);

                       * 經過這樣設置后在多條件情況下,我們不需要再顧及參數的先后順序了

                       */

                      Query query = s.createQuery(hql);

                      query.setString(0, name);

                     

                      /**

                       * Hibernate 分頁: 200-210

                       * query.setFirstResults(200);

                       * query.setMaxResults(10);

                       * 這樣的分頁,為數據庫的移植做到了很好的兼容,根據數據庫設置的方言來判斷

                       */

                      List<User> list = query.list();

                          //Object obj = query.uniqueResult(); 當我們確定返回的結果集就一條記錄,則可調用此方法,如有多條,則會報異常

                      for(User user : list) {

                          System.out.println(user.getName());

                      }

                  } finally {

                      if (s != null) {

                          s.close();

                      }

                  }

          }

          HQL SQL 查詢的區別:

          HQL根據屬性名查對象,SQL根據字段查表

          Creteria:Criteria是一種比HQL更面向對象的條件查詢方式;Criteria的創建方式:

          Criteria crit = session.createCrieria(DomainClass.class);

          簡單屬性條件如:

          criteria.add(Restrictions.eq(propertyName, value);

          criteria.add(Restrictions.eqProperty(propertyName, otherPropertyName));

              staticvoid cri(String name) {

                  Session s = null;

                  try {

                      s = HibernateUtil.getSession();

                      Criteria c = s.createCriteria(User.class);    //對User進行約束查詢

                      c.add(Restrictions.eq("name", name)); //添加約束條件

                      c.add(Restrictions.lt("birthday", new Date()));

                      /**

                       * Criteria 查詢同樣提供了分頁

                       */

                      c.setFirstResult(200);

                      c.setMaxResults(210);

                      List<User> list = c.list();

                      for (User user : list) {

                          System.out.println(user.getName());

                      }

                  } finally {

                      if (s != null) {

                          s.close();

                      }

                  }

          }

          小貼士1、官方推薦HQL 查詢

          2、Hibernate try的異常可以不去操作,因為事務收不到commit事務就會回滾

          八、對象關系的關聯映射

          1.多對一(Employee - Department --- 最常用

          2.一對多(Department - Employee

          3.一對一(Person - IdCard

          4.多對多(Teacher - Student -- 需要建立中間表

          在操作和性能方面都不太理想,所以多對多的映射,實際使用中最好轉換成一對多的對象模型;Hibernate會為我們創建中間關聯表,轉換成兩個一對多。

          <set name="teacher" table="teacher_student">

          <key column="teacher_id"/>

          <many-to-many class="Student" column="student_id"/>

          </set>

          5.組件映射(User - Name

          關聯的屬性是個復雜類型的持久化類,但不是實體,即:數據庫中沒有表與該屬性對應,但該類的屬性要永久保存的。

          <component name="name" class="com.test.hibernate.domain.Name">

          <property name="initial" />

          <property name="first" />

          <property name="last" />

          </component>

          當組件的屬性不能和表中的字段簡單對應的時候可以選擇實現:

          org.hibernate.usertype.UserType or

          org.hibernate.usertype.CompositeUserType

          6.集合映射(setlistmapbag

          絕大部分使用set

          如果習慣使用list,又不想讓Hibernate維護順序,對象里用List,映射時用bag

          映射用listbag

          鍵值對方式用map

          數組因為對元素變化應用不方便

          <set name="employees">

          <key column="depart_id" />

          <one-to-many class="Employee" />

          <!-- <element type="string" column="name" /> -->

          <!--

          <composite-element class="YourClass">

          <property name="prop1" />

          <property name="prop2" />

          </composite>

          -->

          </set>

          7.InversecascadeEmployee - Department


          九、映射文件剖析

          1.hbm.cfg.xml

          a)       

          2.Xxx.hbm.xml

          a)       


          十、
          Hibernate的持久化操作

          1.save() //保存對象

          a)      把臨時對象加載到緩存中,使之成為持久化對象

          b)      使用指定的ID生成器為持久化對象分配OID

          c)      當對象處于持久化狀態Hibernate不允許修改其IOD

          2.update() //修改對象

          a)      把游離對象加入到緩存中,使一個游離對象變成持久化對象

          b)      計劃執行update SQL語句,根據對象IOD來更新對象所對應的數據

          c)      Update不能更新一個在session中已經關聯的相同OID的對象

          3.saveOrUpdate() //保存或修改對象

          a)      同時包含saveupdate方法的功能,根據對象的狀態自動執行相應的功能

          b)      若對象為臨時狀態則執行save,若為游離狀態則執行update方法

          4.merge()//合并對象

          a)      直接修改表中的記錄,并不影響該對象原來的狀態

          5.delete()   //刪除指定的對象

          a)      如果是持久態對象,就計劃執行delete語句

          b)      如果是游離狀態的對象,先使用游離對象被session緩存關聯,變成持久化對象,再計劃執行delete語句

          5.contains() //判斷實體對象是否與session關聯

          a)      可以用此方法判斷對象是否處于持久化狀態

          6.evict() //把實體對象從緩存中移除

          7.clear() //清除session緩存中所有持久化對象

          8.get/load 方法區別:

          a)      都是根據OID從數據庫中加載一個持久化對象

          b)      當數據庫中不存在與OID對象的記錄時,get()返回一個null引用,而load則會拋出ObjectNotFoundException異常

          c)      Load方法可以返回一個實體的代理類實例,而get方法只是直接返回實體類對象

          主站蜘蛛池模板: 皮山县| 城口县| 黄龙县| 麦盖提县| 南通市| 称多县| 那坡县| 吴旗县| 娄烦县| 双牌县| 皮山县| 巧家县| 南投县| 承德县| 土默特右旗| 永平县| 罗平县| 琼海市| 株洲市| 卫辉市| 溧水县| 民和| 河津市| 美姑县| 镇平县| 高州市| 新巴尔虎左旗| 泰安市| 镇原县| 友谊县| 中方县| 阿克陶县| 许昌县| 萨嘎县| 满城县| 荣成市| 花垣县| 会东县| 德江县| 赫章县| 德保县|