<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0

    1.關系模型
     關系模型把世界看作是由實體(Entity)和聯系(Relationship)構成的;在關系模型中實體通常是以表的形式來表現的。表的每一行描述
     實體的一個實例,表的每一列描述實體的一個特征或屬性;所謂聯系就是指實體之間的關系,即實體之間的對應關系;
    2.ORM-對象關系映射
     ORM是通過使用描述對象和數據庫之間映射的元數據,將java程序中的對象自動持久化到關系數據庫中;它實現了Java應用中的對象到關系數據庫中的表的自動的(和透明的)持久化;當你開發一個應用程序的時候(不使用O/R Mapping),你可能會寫不少數據訪問層的代碼,用來從數據庫保存,刪除,讀取對象信息等。而這些代碼寫起來總是重復的。
      個人建議:可以去看看Spring的JdbcTemplate
    3.Hibernate-
     提供了強大的對象和關系數據庫映射以及查詢功能。

     持久化Java類必須遵循的原則:
         對JavaBeans風格的屬性實行持久化/getter/setter/
         默認的構造方法->Constructor.newInstance()
         集合類型的屬性,它的類型必須定義為集合的接口
         提供一個標識屬性(identifier property)->如級聯更新等(更新主鍵值的操作,該值由其它表的現有行中的外鍵列引用。在級聯更新中,更新所有外鍵值以與新的主鍵值相匹配)
         ......

         持久化類(POJO)- *.hbm.xml -數據庫結構(schema)【xdoclet/hbm2java(code generator)/SchemaExport(hbm2dll)/Middlegen】

     配置Hibernate:
      開發hibernate3.0必須的包:
       hibernate3.jar
       required:antlr、dom4j、CGLIB、asm、Commons Collections、Commons Logging、 EHCache->oscache
       Hibernate底層還需要Java Transaction API-jta.jar
      將\etc目錄下的log4j.properties復制至Hibernate項目的Classpath下,并修改一下當中的log4j.logger.org.hibernate為error,也就是只在在錯誤發生時顯示必要的訊息
       配置文件.xml/.properties
       hibernate.cfg.xml:

     1<?xml version="1.0" encoding="utf-8"?>
     2   <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     3   "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
     4    <hibernate-configuration>
     5        <session-factory>
     6         <!-- 顯示實際操作數據庫時的SQL -->
     7      <property name="show_sql">true</property>
     8      <!-- SQL方言,這邊設定的是MySQL -->
     9      <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    10       <!-- JDBC驅動程序 -->
    11      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    12      <!-- JDBC URL -->
    13       <property name="connection.url">jdbc:mysql://localhost/demo</property>
    14      <!-- 數據庫使用者 -->
    15      <property name="connection.username">root</property>
    16      <!-- 數據庫密碼 --> 
    17       <property name="connection.password">root</property>
    18         <!-- 以下設置對象與數據庫表格映像文件 -->
    19     </session-factory>
    20    </hibernate-configuration>
    21


         *.hbm.xml-告訴 Hibernate您所定義的*實例如何映射至數據庫表,以Use為例:user.hbm.xml-
        

     1 <?xml version="1.0" encoding="utf-8"?>
     2  <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"     
     3  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4   <hibernate-mapping>  
     5    <class name="com.db.hibernate.demo.User" table="user">    
     6     <id name="id" column="id" type="java.lang.Integer">
     7     <!-- 主鍵的生成方式由Hibernate根據數據庫Dialect的定義來決定 -->
     8     <generator class="native" /> 
     9     </id>    
    10     <property name="name" column="name" type="java.lang.String" />    
    11     <property name="age" column="age" type="java.lang.Integer" />  
    12    </class>
    13  </hibernate-mapping>
    14


        需要在Hibernate配置文件hibernate.cfg.xml中指明映像文件的位置
     詳見eclipse的db工程
    4.配置文件的問題:
     1.The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".
      解決:1.可能是文件編碼問題;我的hibernate.cfg.xml是從ppt拷貝出來的,文件編碼有問題;從正確的機器上拷貝一份文件或
      者嘗試重新編碼或者從網上拷貝一份正確的然后修改(正確的方法是參考etc目錄下的xml模板)
       2.可能是元素(element type)的順序問題
       3.可以將hibernate-configuration-3.0.dtd下載下來,對比一下,看哪里出錯
     2.hibernate.cfg.xml和*.hbm.xml目前只能放到src根目錄下,放到其他目錄總報錯
     3.關于xml dtd,正常下載的jar包中都會有dtd文件的,如hibernate-configuration-3.0.dtd;dom4j解析的時候會優先驗證本地,如果本地有,則不會連接dtd指定的服務器地址;如果沒有的話,可以去那地址下載dtd,放在本地或者將地址改為本地dtd的位置;當然eclipse也由一個選項,window->preference->xml catalog,可以添加;詳見xml選項
    5.Criteria
     Criteria對SQL進行封裝,對于不甚了解SQL的開發人員來說,使用Criteria也可以輕易的進行各種數據的檢索;Expression設定查詢條件(Expression已被廢棄,eclipse中添加hibernate的javadoc,方便查看)Criteria是對象導向式的查詢方式,讓不了解SQL的開發人員也可以輕易進行各項查詢;但Criteria的API目前還不是很完善;Hibernate鼓勵的查詢方式,是透過HQL(Hibernate Query Language)來進行.
    6.Query接口
    7.hibernate配置文件-hibernate.cfg.xml(提供較好的結構與配置方式,hibernate建議使用,默認)/hibernate.properties
         注意:XML配置文件的位置必須在Classpath下;默認的XML配置文件名稱是hibernate.cfg.xml;你可以自己指定配置文件:
         new Configuration().configure().configure("db.cfg.xml");
     在Hibernate下載檔案中的etc目錄下,有hibernate.cfg.xml與hibernate.properties可供設定參考properties檔案中不包括映射文件的名稱,需要編程方式:
     Configuration cfg = new Configuration().addClass("user.hbm.xml") .addClass(com.db.hibernate.demo.User.class);

     hibernate.properties:
     hibernate.show_sql = true
     hibernate.dialect = org.hibernate.dialect.MySQLDialect
     hibernate.connection.driver_class = com.mysql.jdbc.Driver
     hibernate.connection.url = jdbc:mysql://localhost/demo
     hibernate.connection.username = root
     hibernate.connection.password = root
    8.Configuration-
     Configuration的實例管理Hibernate的配置信息,通常用于建立SessionFactory
     SessionFactory sessionFactory = config.buildSessionFactory();
    9.SessionFactory-
     SessionFactory一旦建立,就被賦予當時Configuration的配置信息;即使改變Configuration也不會影響之前已建立的該實例,而會新建SessionFactory中包括了數據庫配置及映射關系,它的建立相當復雜,所以使用時需考慮到重用已建立的SessionFactory實例SessionFactory是被設計為線程安全的(Thread-safe)
    10.設定數據庫連接-
     設定connection.pool_size是Hibernate默認的連接池設定;通常只用于開發階段測試之用
     <!-- Hibernate 預設的Connection pool -->     
     <property name="connection.pool_size">2</property> 
         使用C3P0連接池,需要包含c3p0-*.jar;也可以使用Proxool或DBCP連接池(etc目錄hibernate.properties中的配置例子來參考)使用Tomcat的話,您也可以通過它提供的DBCP連接池來取得連接-配置中加入connection.datasource屬性
    11.hibernate緩存
     Hibernate中Session level緩存會在使用主鍵加載資料或是延遲初始(Lazy Initialization) 時作用Session level緩存,Session會維護一個Map容器
     通過evict()將某個對象從緩存中移去,可以使用clear()清除緩存中的所有對象
     可以通過session的load方法和==來判斷是否存在緩存

     Session在使用save()儲存對象時,會將要儲存的對象納入Session level緩存管理,在進行大量數據儲存時,緩存中的實例大量增加最后會導致OutOfMemoryError,可以每隔一段時間使用Session的 flush()強制儲存對象,并使用clear()清除緩存

     1 1 Session session = sessionFactory.openSession();
     2 2  Transaction tx = session.beginTransaction(); 
     3 3  while(.)
     4 4  
     5 5   // 大量加載對象時的循環示意    
     6 6   .    
     7 7   session.save(someObject);    
     8 8   if(count % 100 == 0
     9 9   
    1010    // 每100筆資料        
    1111    session.flush(); 
    1212    // 送入數據庫        
    1313    session.clear(); 
    1414    // 清除緩存    
    1515   }

    1616  }
     
    1717  tx.commit();
    1818  session.close();
    19


      配置中hibernate.jdbc.batch_size來控制每多少筆資料就送至數據庫(MySQL中則不支持這個功能,sqlserver/oracle支持)
    12.事務
     事務是一組原子(Atomic)操作(一組SQL執行)的工作單元;事務中的所有原子操作,不是全部執行成功,就是全部失敗(即使只有一個失敗,所有的原子操作也要全部撤消(回滾))JDBC中通過Connection的setAutoCommit和Commit方法管理事務,異常則回滾;Hibernate本身沒有事務管理功能,它依賴于JDBC或JTA(java transaction api)的事務管理功能;默認是使用JDBC事務管理
     配置中添加:hibernate.transaction.factory_class屬性來指定Transaction的工廠類別
     <property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JDBCTransactionFactory</property> 
     Hibernate基于JDBC的事務管理只是對JDBC作了個簡單的封裝:

     1 try 
     2  {     
     3   session = sessionFactory.openSession();      
     4   Transaction tx = session.beginTransaction();     
     5   .      
     6   tx.commit();  // 必須commit才會更新數據庫
     7  }
     
     8  catch(HibernateException e)
     9  {    
    10   tx.rollback(); 
    11  }


      在一開始的openSession()取得Session時,JDBC的Connection實例之AutoCommit就被設定為false,在 beginTransaction()時,會再度檢查Connection實例的AutoCommit為false,在操作過程中,最后要commit (),否則的話對數據庫的操作不會有作用,如果操作過程中因發生例外,則最后commit()不會被執行,之前的操作取消,執行rollback()可撤消之前的操作。要使用MySQL中的事務處理,必須建立事務表類型的表格例如InnoDB的表格
    13.映射文件
     Hibernate 中將對象與數據庫表格映射關系連接起來的是映射文件;通常以*.hbm.xml作為文件名稱;手工撰寫;通過工具程序從數據庫表格自動生成;通過工具程序從Java類自動生成三部分:類名稱與表格名稱的映射;id屬性與主鍵的映射;類屬性與表格字段的映射

     1<?xml version="1.0" encoding="utf-8"?>
     2 <!DOCTYPE hibernate-mapping       PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"       
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
     4 <hibernate-mapping>    
     5  <!--類別名稱與表格名稱映像-->    
     6 <class name="onlyfun.caterpillar.User" table="user">      
     7  <!--id與主鍵映像-->      
     8  <id name="id" column="id" type="java.lang.Integer">        
     9   <generator class="native"/>      
    10  </id>      
    11  <!--類別屬性與表格字段的映像-->      
    12  <property name="name" column="name" type="java.lang.String"/>      
    13  <property name="age" column="age" type="java.lang.Integer"/>    
    14 </class>  
    15 </hibernate-mapping> 
    16


      注:
      1.Java的數據類型與數據庫的數據類型并不是一對一對應的,為此Hibernate提供它自己的數據類型,作為Java數據類型與數
      據庫數據類型的連接類型
      2.<generator>設定主鍵的生成方式;“native”表示由Hibernate自動根據Dialect選擇采用 identity、hilo、sequence等作為主鍵生成方
      式;可以考慮采用uuid由Hibernate根據128位UUID算法(128- bit UUID algorithm)生成16進位制數值,并編碼為32位長度的字符
      串
    14.基本API
         1.Session-是Hibernate操作的基礎;不是設計為線程安全;一個Session由一個線程使用;
         Hibernate在對數據庫進行操作之前,必須先取得Session實例,相當于JDBC在對數據庫操作之前,必須先取得Connection實例;過Session,可以對數據庫進行新增、刪除、更新;使用save()新增一條記錄;使用get()或load()方法取得id為1的記錄-User user = (User) session.get(User.class, new Integer(1));
     如果未能發現相符合的記錄,則get()方法會返回null,而load()方法會丟出ObjectNotFoundException;在高級的應用中,load()方法可以返回代理對象,并可充分利用緩沖機制
     Hibernate 3中,取消了find()方法,您必須通過Query或Criteria來進行記錄查詢
         使用delete()刪除資料
      1 User user = (User) session.get(User.class, new Integer(1));
       session.delete(user);
      2 Query q=session.createQuery(“delete User u where u.id=1”);
       q.executeUpdate();
      3 Session.delete(“from User u where u.id=1”);
         使用update()方法將對象中的資料更新至對應的數據表中
     Session提供了一個saveOrUpdate()方法:由定義映射文件時,設定<id>卷標的unsaved-value來決定
     Session如同在編寫JDBC時需關心 Connection的管理,以有效的方法創建、利用與回收Connection,以減少資源的消耗,增加系統
     執行效率一樣;SessionFactory是線程安全的(Thread-safe),然而Session則不是設計為線程安全的,所以試圖讓多個執行緒共享一個
     Session,將會發生資料共享而發生混亂的問題
     2.Session管理
      使用了ThreadLocal類來建立一個Session管理的輔助類,這是Hibernate的Session管理一個廣為應用的解決方案
      Thread-Specific Stroage模式可以有效隔離線程所使用的資源,所以避開Session的多線程之間的資源共享問題
      ThreadLocal是*Thread-Specific Storage 模式*的一個運用實例
      Hibernate會在真正需要數據庫操作時才(從連接池中)取得Connection
      在Web應用程序中,可以藉由Filter來進行Session管理,在需要的時候開啟Session,并在Request結束之后關閉Session
     3.Criteria基本查詢
      Criteria對SQL進行封裝,讓開發人員可以用對象的方式來對數據庫進行操作
      Criteria criteria = session.createCriteria(User.class);
      // 查詢user所有字段
      List<User> users = criteria.list();
      Criteria實際上只是個容器,如果想要設定查詢條件,則要使用add()方法加入Restrictions的條件限制
      例如查詢age大于20且小于40的資料:

    1Criteria criteria = session.createCriteria(User.class);
    2  criteria.add(Restrictions.gt("age"new Integer(20)));//greater than >
    3  criteria.add(Restrictions.lt("age"new Integer(40)));//lesser than <
    4  List<User> users = criteria.list();


      也可以使用邏輯組合來進行查詢-criteria.add(Restrictions.or(Restrictions.eq(), Restrictions.isNull())
      sqlRestriction()方法來提供SQL語法作限定查詢
      criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));//alias別名
      在SQL撰寫時,不必再寫WHERE
      criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
      Restrictions的幾個常用限定查詢方法:eq/allEq/gt/ge/lt/le/between/like/in/and/or/sqlRestriction
     4.Criteria高級查詢
      使用Criteria進行查詢,并使用Order對結果進行排序
      criteria.addOrder(Order.asc("age"));//desc()
      setMaxResults()方法可以限定查詢回來的記錄數;setFirstResult()設定傳回查詢結果第一個記錄的位置
      這兩個配合起來,就可以實現簡單的分頁
      對查詢結果進行統計動作,使用Projections的avg()、rowCount()、count()、max()、min()、countDistinct()等方法
      criteria.setProjection(Projections.avg("age"));
      可以配合Projections的groupProperty()來對結果進行分組
      criteria.setProjection(Projections.groupProperty("age"));
      想結合統計與分組功能,則可以使用ProjectionList

    1ProjectionList projectionList = Projections.projectionList();
    2   projectionList.add(Projections.groupProperty("age"));
    3   projectionList.add(Projections.rowCount()); 
    4   Criteria criteria = session.createCriteria(User.class);
    5   criteria.setProjection(projectionList);


      使用Example對象,可以將一個已知的對象作為查詢的依據
      criteria.add(Example.create(user));
      Criteria可以進行復合查詢
      Criteria與Session綁定,其生命周期跟隨著Session結束而結束;使用Criteria時進行查詢時,每次都要于執行時期動態建立對象
      能夠重復使用Criteria對象,在Hibernate 3.0中新增了DetchedCriteria對象;您可以先建立DetchedCriteria實例,并加入各種查詢條
      件,并于需要查詢時再與Session綁定,獲得一個綁定Session的Criteria對象

    1// 先建立DetchedCriteria對象
    2   DetachedCriteria detchedCriteria=DetachedCriteria.forClass(User.class);
    3   // 加入查詢條件
    4   detchedCriteria.add(Restrictions.ge("age",new Integer(25)));        
    5   Session session = sessionFactory.openSession();
    6   // 綁定Session并返回一個Criteria實例
    7   Criteria criteria = detchedCriteria.getExecutableCriteria(session); 
    8


        5.Query接口
      使用org.hibernate.Query接口的實例來進行查詢;
      透過Query接口,您可以先設定查詢參數,使用setXXX()等方法,將指定的參數值填入,而不用每次都撰寫完整的HQL
      在設定參數值時,必須依照 ? 所設定的順序,并使用對應類型的setXXX()方法
      也可以使用命名參數(Named Parameter)
      將HQL撰寫在程序之;避免硬編碼(Hard code)在程序之中,在需要修改HQL時就很方便;
      在*.hbm.xml中使用<query/>卷標,并在<![CDATA[與]] >之間撰寫HQL,撰寫的位置是在</hibernate-mapping>之前
      (CDATA-character data)

     1 <?xml version="1.0" encoding="utf-8"?>
     2  <!DOCTYPE hibernate-mapping      
     3  PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"       
     4  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
     5 <hibernate-mapping>    
     6  <class name="model.User" table="user">       
     7   <id name="id" column="id“ type="java.lang.Integer">         
     8   <generator class="native"/>      
     9   </id>      
    10   <property name="name" column="name" type="java.lang.String"/>   
    11   <property name="age" column="age" type="java.lang.Integer"/>   
    12  </class>    
    13  <query name=“model.QueryUser">       
    14   <![CDATA[
    15   select user.name from User as user where user.age >:minAge 
    16   ]]>         
    17  </query>  
    18 </hibernate-mapping>
    19


       <query>的name屬性用來設定查詢外部HQL時的名稱依據
      Query query = session.getNamedQuery(“model.QueryUser");
      query.setInteger("minAge", 25); 
    15.HQL
     1.HQL基本查詢
      查詢指定類對應表格的所有記錄
      Query query = session.createQuery("from User"); //也可以指定類的全稱
      List names = query.list();
      HQL本身不區分大小寫,不過要注意類的名稱必須區分大小寫
      Hibernate會自動判定繼承關系,如果查詢的類是某類的父類,則會返回與父類、子類對應的所有表格記錄
      針對某個屬性作查詢-Query query = session.createQuery("select user.name from User as user"); 
      查詢兩個以上的屬性,查詢的結果會以數組的方式返回
      Query query = session.createQuery("select user.age, user.name from User as user"); Object[] obj = (Object[]) iterator.next();
      如果User類提供有適當的構建方法,則可以在使用HQL時直接指定新建一個對象傳回-
      Query query = session.createQuery("select new User(user.name, user.age) from User as user");
      List names = query.list();User user= (User) iterator.next(); //這個返回的User實例并未與數據庫有任何關聯
      使用distinct去除資料重復的記錄-Query query = session.createQuery("select distinct user.age from User as user");
      在HQL中使用函數-Query query = session.createQuery("select count(*) from User as user"); 
      使用avg()取得屬性的平均值-Query query = session.createQuery("select avg(user.age) from User as user");
      使用upper()函數將字符串轉為大寫:Query query = session.createQuery("select upper(user.name) from User as user"); 
     2.where 子句
      使用where子句來限定查詢的條件,除了 = 運算之外,還有 >、>=、<、<=、!= 或 <>等比較運算
      Query query = session.createQuery("from User user where user.name=‘cjy'"); 
      where子句上進行表達式-Query query = session.createQuery("from User user where (user.age / 10 = 3)");
      在where子句上使用and、or-Query query = session.createQuery("from User user where (user.age > 20) and (user.name = ‘cjy')");
      is not nullL與is null則可以測試字段值是否為空值Query query = session.createQuery("from User user where user.name is not null");
      between可以測試字段值是否在指定的范圍之內-session.createQuery("from User user where user.age between 20 and 30");
      使用in或not in來測試字段值是否在您指定的集合中-session.createQuery("from User user where user.name in(‘cjy', ‘abc')");
      like或not like可以讓您進行模糊條件搜尋-session.createQuery("from User user where user.name like ‘c%'");
      查詢結果使用order by進行排序-session.createQuery("from User user order by user.age");
      可使用desc反排序-session.createQuery("from User user order by user.age desc");
      同時指定兩個以上的排序方式-
      session.createQuery("from User user order by user.age desc, user.name");//先按照"age"反序排,"age"相同,則按照"name"順序排列
      使用GROUP BY子句,自動將指定的字段依相同的內容群組-
      session.createQuery("select user.sex, avg(user.age) from User user group by user.sex");
      結合having子句-session.createQuery("select user.sex, avg(user.age) from User user group by user.sex having avg(user.age) > 20");
      在Hibernate 3中,HQL新增了update與delete語句,可以直接使用HQL指定更新或刪除
      update子句進行更新-session.createQuery("update User set name=‘abc' where name=‘cjy'");query.executeUpdate();
      delete子句進行資料刪除-session.createQuery("delete User where name=‘cjy'");query.executeUpdate();
    16.SQL支持
     Hibernate提供了對SQL的支持,您可以指定您所要建立的SQL,并將實體類與資料表格關聯;
      // SQL,并指定別名為user

    1String sql = "select {user.*} from User user where user.age > 20";
    2  Session session = sessionFactory.openSession();
    3  // 建立 SQLQuery
    4  SQLQuery sqlQuery = session.createSQLQuery(sql);
    5  // 將別名user與實體類User關聯在一起
    6  sqlQuery.addEntity("user", User.class);
    7  Iterator iterator = sqlQuery.list().iterator();
    8


       addEntity()是將實體類與別名連結在一起的方法,大括號指定要查詢的記錄
     也可以將SQL語句定義在映射文件中*.hbm.xml
     <sql-query name="model.QueryUser">    
     <![CDATA[                   
      select {user.*} from User user where user.age > 20             
     ]]>             
     <return alias="user" class="model.User"/>  
     </sql-query> 
      Query query = session.getNamedQuery(“model.QueryUser");
      Iterator iterator = query.list().iterator();
      可以設定查詢參數;
       <sql-query name=“model.QueryUser">
       <![CDATA[
        select {user.*} from User user where user.age > :age
       ]]>
       <return alias="user" class=“model.User"/>
       </sql-query>
        Query query = session.getNamedQuery("model.QueryUser");
        query.setInteger("age", 20); 
     Hibernate 3的映射文件中新增了<sql-insert>、<sql-update>與<sql-delete>三個卷標,您可以在這三個卷標中使用SQL自定義您的
     INSERT、UPDATE、DELETE

    1 <sql-insert>       
    2   INSERT INTO user (name, age) VALUES (?, ?)              
    3  </sql-insert>     
    4  <sql-update>       
    5   UPDATE user SET name=?, age=?, WHERE id=?              
    6  </sql-update>      
    7  <sql-delete>       
    8    DELETE FROM user WHERE id=?              
    9  </sql-delete>

        
      ? (參數) 對應的順序是映像文件中屬性出現的順序
    17.映射基礎
         Hibernate中的實體對象可以分為三種狀態:Transient、Persistent、Detached。
         Transient-如User類所衍生出之對象,在還沒有使用save()之前都是暫存對象,這些對象還沒有與數據庫發生任何的關系,不對應于數據庫中的任一條記錄。 
         Persistent-當對象與數據庫中的記錄有對應關系,并且與Session實例有關聯而Session 實例尚未關閉(close),則它是在Persistent狀態;Persistent狀態的對象對應于數據庫中的一條記錄,對象的id值與記錄的主鍵值相同,并且Session實例尚未失效;在這期間您對對象的任何狀態變動,在Session實例關閉(close)或Transaction實例執行commit()之后,數據庫中對應的記錄也會跟著更新Session實例關閉(close),則Persistent狀態的對象會成為Detached狀態;使用Session的實例delete()方法刪除記錄,Persistent狀態的對象由于失去了對應的記錄,則它會成為Transient狀態。
         Detached-Detached狀態的對象,其id與數據庫的主鍵值對應;Detached狀態的對象之任何屬性變動,不會對數據庫中的記錄造成任何的影響;Detached狀態的對象可以使用update()方法使之與數據庫中的對應記錄再度發生關聯,此時Detached狀態的對象會變為 Persistent狀態。

         Transient與Detached狀態的對象未受Hibernate持久層管理員管理,對這兩個狀態的對象作任何屬性變動,不會對數據庫中的記錄有任何的影響;而Persistent狀態的對象受Hibernate持久層管理,對對象的屬性變動,在Session實例關閉(close)或 Transaction實例執行commit()之后,數據庫中對應的記錄也會跟著更新。在對象為Persistent時,如果對象的屬性發生變化,并且尚未提交之前,對象所攜帶的資料稱之為Dirty Data,Hibernate會在持久層
     維護對象的最近讀取版本,并在資料提交時檢查兩個版本的屬性是否有變化,如果有的話,則將數據庫中的記錄進行更新。

     對象識別:
      要有必要比較透過查詢后兩個對象的資料是否相同(例如當對象被儲存至Set時)您必須重寫 equals()與hashCode()
      重寫方法之一,equals()與hashCode()的方法是根據數據庫的identity,就是透過getId()方法取得對象的id值并加以比較

     1public class User 
     2  {    
     3   .     
     4   public boolean equals(Object o) 
     5   {        
     6    if(this == o) return true;       
     7    if(id == null || !(o instanceof User)) 
     8     return false;         
     9    final User user == (User) o;        
    10    return this.id.equals(user.getId());    
    11    }
         
    12   public int hasCode() 
    13   {        
    14    return id == null ? System.identityHashCode(this):id.hashcode();    
    15   }
     
    16  }

    17

      
      上面的例子是個不被鼓勵的例子,因為當一個對象被new出來而還沒有save()時,它并不會被賦予id值,這時候就不適用這
      個方法;
     比較被采用的方法是根據對象中真正包括的的屬性值來作比較;
     可以使用org.apache.commons.lang.builder.EqualsBuilder與 org.apache.commons.lang.builder.HashCodeBuilder來協助定義equals()與
     hashCode();
      Return new EqualsBuilder().append(this.name,user.getName()).append(this.phone, user.getPhone()).isEquals();
      return new HashCodeBuilder().append(this.name).append(this.phone).toHashCode();
    18.實體映射/集合映射/關系映射/繼承映射/緩存/鎖定/回調與攔截/工具
    19.Annotation-
     可以不通過*.hbm.xml,完全通過annotation搞定
     hibernate.cfg.xml-
     <!-- 以下設置對象與數據庫表格映像類別 -->
            <mapping class="com.db.hibernate.demo.User"/>

     實體標識,主鍵生成,以及相關映像,都可以使用Annotation來完成;

     1@Entity
     2 @Table(name="user"// 非必要,在表格名稱與類別名稱不同時使用
     3 public class User
     4 {
     5  @Id
     6  @GeneratedValue(strategy=GenerationType.AUTO)
     7   private Integer id;
     8
     9  @Column(name="name"// 非必要,在字段名稱與屬性名稱不同時使用
    10  private String name;
    11  
    12  @Column(name="age"
    13  private Integer age; // 非必要,在字段名稱與屬性名稱不同時使用
    14    
    15   // 必須要有一個預設的建構方法
    16    // 以使得Hibernate可以使用Constructor.newInstance()建立對象
    17   public User() {    }
    18 }

    19


      注意:import javax.persistence.*中的注解

     使用Annotation時,需要的是AnnotationConfiguration類;

    1// 需要AnnotationConfiguration讀取Annotation訊息
    2  Configuration config = new AnnotationConfiguration().configure();
    3  // 根據 config 建立 SessionFactory
    4  // SessionFactory 將用于建立 Session
    5   SessionFactory sessionFactory = config.buildSessionFactory();

     

    posted on 2011-12-26 23:11 landon 閱讀(1874) 評論(1)  編輯  收藏 所屬分類: 學習筆記

    FeedBack:
    # re: Hibernate學習筆記
    2015-03-09 13:42 | zuidaima
    java hibernate demo使用實例教程源代碼下載:http://zuidaima.com/share/khibernate-p1-s1.htm  回復  更多評論
      

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 最近2019中文字幕mv免费看| 精品免费视在线观看| 91青青青国产在观免费影视| 精品国产亚洲男女在线线电影| 色天使亚洲综合一区二区| 日韩在线a视频免费播放| 亚洲av永久无码| 亚洲乱亚洲乱少妇无码| 国产免费久久精品丫丫| 亚洲AV永久无码精品成人| 中文字幕免费高清视频| 亚洲人成在线免费观看| 暖暖免费高清日本中文| 国产免费MV大全视频网站| 亚洲国产综合91精品麻豆| 18禁男女爽爽爽午夜网站免费| 亚洲制服在线观看| 国产男女性潮高清免费网站 | 1000部夫妻午夜免费| 97se亚洲国产综合自在线| 色播在线永久免费视频| 福利片免费一区二区三区| 久久久久亚洲精品中文字幕| 国产婷婷成人久久Av免费高清 | 亚洲国产精品嫩草影院久久 | 亚洲αⅴ无码乱码在线观看性色| 四虎影库久免费视频| 青柠影视在线观看免费高清| 亚洲国产精品久久久久秋霞影院| 在线免费观看视频你懂的| 九九久久国产精品免费热6| 亚洲欧洲校园自拍都市| 好爽好紧好大的免费视频国产| 51午夜精品免费视频| 亚洲综合在线成人一区| 国产裸模视频免费区无码| 免费无码一区二区三区| 国产亚洲蜜芽精品久久| 中文字幕亚洲色图| 国产禁女女网站免费看| 成人电影在线免费观看|