SSH之Hibernate總結篇

Hibernate

hibernate 簡介:

  hibernate是一個開源ORM(Object/Relationship Mipping)框架,它是對象關聯關係映射的持久層框架,它對JDBC作了輕量級的封裝,而咱們java程序員可使用面向對象的思想來操縱數據庫。java

  

 

爲何要用hibernate(jdbc的缺點):

  一、編程的時候很繁瑣,用的try和catch比較多mysql

  二、jdbc沒有作數據的緩存程序員

  三、沒有作到面向對象編程web

  四、sql語句的跨平臺性不好sql

 

JDBC的優勢:

  效率高!數據庫

 

hibernate的優勢:

  一、徹底的面向對象編程編程

  二、hibernate的緩存很牛的,一級緩存,二級緩存,查詢緩存   重點緩存

  三、編程的時候就比較簡單了安全

  四、跨平臺性很強session

  五、使用場合就是企業內部的系統

 

hibernate的缺點:

  一、效率比較低

  二、表中的數據若是在千萬級別,則hibernate不適合

  三、若是表與表之間的關係特別複雜,則hibernate也不適合

 

Hibernate所需包說明:

     說明:

              javassist包是用來建立代理對象的

                代理對象的三種建立方式:

                        一、jdkproxy

                        二、cglib

                        三、javassist

             jta: Java Transaction API,是sun公司給分佈式事務處理出來的規範

 

hibernate.cfg.xml:

    主要的用途:

              告訴hibernate鏈接數據庫的信息,用的什麼樣的數據庫(方言)

              根據持久化類和映射文件生成表的策略

 

五個核心接口:

  • Configuration:負責配置並啓動hibernate,建立SessionFactory  
  • SessionFactory:負責初始化hibernate,建立session對象
    • 一、hibernate中的配置文件、映射文件、持久化類的信息都在sessionFactory中
    • 二、sessionFactory中存放的信息都是共享的信息
    • 三、sessionFactory自己就是線程安全的
    • 四、一個hibernate框架sessionFactory只有一個
    • 五、sessionFactory是一個重量級別的類
  • Session:負責被持久化對象CRUD操做
    • 一、獲得了一個session,至關於打開了一次數據庫的鏈接
    • 二、在hibernate中,對數據的crud操做都是由session來完成的

    Transaction:負責事物相關的操做
    • hibernate中的事務默認不是自動提交的

        設置了connection的setAutoCommit爲false

              只有產生了鏈接,才能進行事務的操做。因此只有有了session之後,纔能有transaction

  • Query:負責執行各類數據庫查詢

 

hibernate.cfg.xml文件的加載:

 1 <?xml version='1.0' encoding='utf-8'?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <!-- 
 7  一個sessionFactory表明數據庫的一個鏈接 8 --> 9 <session-factory> 10 <!-- 連接數據庫的用戶名 --> 11 <property name="connection.username">root</property> 12 <!-- 連接數據庫的密碼 --> 13 <property name="connection.password">root</property> 14 <!-- 連接數據庫的驅動 --> 15 <property name="connection.driver_class"> 16  com.mysql.jdbc.Driver 17 </property> 18 <!-- 連接數據庫的url --> 19 <property name="connection.url"> 20 jdbc:mysql://localhost:3306/itheima12_hibernate 21 </property> 22 <!-- 23  方言 24  告訴hibernate使用什麼樣的數據庫,hibernate就會在底層拼接什麼樣的sql語句 25 --> 26 <property name="dialect"> 27  org.hibernate.dialect.MySQLDialect 28 </property> 29 <!-- 30  根據持久化類生成表的策略 31  validate 經過映射文件檢查持久化類與表的匹配 32  update 每次hibernate啓動的時候,檢查表是否存在,若是不存在,則建立,若是存在,則什麼都不作了 33  create 每一次hibernate啓動的時候,根據持久化類和映射文件生成表 34 create-drop 35 --> 36 <property name="hbm2ddl.auto">update</property> 37 <property name="show_sql">true</property> 38 <mapping 39 resource="com/itheima12/hibernate/domain/Person.hbm.xml" /> 40 <mapping 41 resource="com/itheima12/hibernate/utils/Person.hbm.xml" /> 42 </session-factory> 43 </hibernate-configuration>

 

 

hibernate.cfg.xml文件的加載:

屬性名字 含義  
hibernate.show_sql 是否把Hibernate運行時的SQL語句輸出到控制檯,編碼階段便於測試
hibernate.format_sql 輸出到控制檯的語句是否進行排版,便於閱讀,建議設置爲true
hbm2ddl.auto 能夠幫助由java代碼產生數據庫腳本,進而生成具體的表結構(create|update|create drop|validate)
hibernate.default_schema 默認的數據庫
hibernate.dialect 配置Hibernate數據庫方言,Hibernate可針對特殊的數據庫進行優化

                        注:hibernate的前綴能夠省略,即:hibernate.dealict==dealect

 

表的生成策略:

1  <id name="pid" type="java.lang.Long">
2     <column name="pid" />
3    <generator class="increment" />
4  </id>

  increment:先找到主鍵的最大值,在最大值基礎上+1

  identiry:表的自動增加機制,主鍵必須是數字類型,效率比increment高,但id值不連續

  sequence:

  native:

  assigned:在程序中手動設置主鍵的值

  uuid:

 

Hibernate的執行流程:

  1. 開始
  2. 啓動Hibernate
  3. 構建Configuration實例
    1 Configuration configuration = new Configuration().configure();
  4. Configuration實例加載hibernate.cfg.xml文件至內存
  5. Configuration實例根據hibernate.cfg.xml文件加載映射文件(*.hbm.xml)至內存
  6. Configuration實例構建一個SessionFactory實例
    1 SessionFactory sessionFactory = configuration.buildSessionFactory();
  7. SessionFactory實例建立Session實例
    1 Session session1 = sessionFactory.openSession();             //不會自動關閉session
    2 Session session2 = sessionFactory.getCurrentSession();    //會自動關閉session
       //調用getCurrentSessio()必須在hibernate.cjf.xml文件中進行配置<property name="hibernate.current_session_context_class">thread</property>
  8. 由Session實例建立Transaction的一個實例,開啓事務
    1 Transaction tanTransaction = session1.beginTransaction();
  9. 經過Session接口提供的各類方法操做數據庫
     1 public Serializable save(Object object) throws HibernateException;
     2 public Serializable save(String entityName, Object object) throws HibernateException;
     3 public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException;
     4 public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
     5 public Object load(Class theClass, Serializable id) throws HibernateException;
     6 public Object load(String entityName, Serializable id) throws HibernateException;
     7 public Object load(String entityName, Serializable id) throws HibernateException;
     8 public void update(Object object) throws HibernateException;
     9 public void update(String entityName, Object object) throws HibernateException;
    10 public void delete(Object object) throws HibernateException;
    11 public void delete(String entityName, Object object) throws HibernateException;
    12 public Transaction beginTransaction() throws HibernateException;
    13 public SQLQuery createSQLQuery(String queryString) throws HibernateException;
    14 public Query createQuery(String queryString) throws HibernateException;
    15 public void clear();
    16 public Object get(Class clazz, Serializable id) throws HibernateException;
    17 public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException;
    18 public Object get(String entityName, Serializable id) throws HibernateException;
    19 public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
  10. 提交事務或回滾事務
    1 tanTransaction.commit();
    2 tanTransaction.rollback();
  11. 關閉Session
    1 session1.close();
    2 sessionFactory.close();
  12. 結束

 

查詢操做之get和load的區別: 

1 Student student1 = (Student)session.get(Student.class,1);
2 Student student2 = (Student)session.load(Student.class,1);

  兩個方法都是從數據庫獲取數據

    get():若數據庫無此數據,則返回null;

    load():懶加載模式,若數據庫無此數據,則會報錯ObjectNotfountException異常,

  因此,load加載數據必定要保證其數據存在。

 

flush()

  

  

 

openSession與getCurrentSession的區別:

  • getCurrentSession在事務提交或回滾以後會自動關閉,而openSession須要手動關閉。若是使用openSession沒有手動關閉,屢次使用以後可能會致使鏈接池溢出。
  • openSession每次建立新的Session對象,getCurrentSession使用現有的Session對象。

 

hbm經常使用的設置:

  <hibernate-mapping  //屬性

    schema="schemaName"  //模式的名字

    catelog="catelogName"  //目錄的名稱

    default-cascade="cascade_style"  //級聯風格

    default-access="field|property|ClassName"    //訪問策略

    default-lazy="true|false"    //加載策略

    package="packagename"

  />

 

  <class

    name="ClassName"  //映射的類名

    table="tableName"  //對應數據庫的映射表名

    batch-size="N"    //抓取策略,一次住多少條數據

    where="condition"  //條件

    entity-name="EntityName"  //支持同一個類映射成多個表名(用的少)

  />

 

  <id

    name="propertyName"

    type="typeName"

    column="colunm_name"

    length="length"

    <generator class="generatorClass"/>

  />

 

Query

  1. 得到Hibernate Session對象
    1 Session session = sessionFactory.openSession();
  2. 編寫HQL(Hibernate Query Language)語句
    1 String hql = "from Student";  //這裏值得注意的是Student是java bean對象
  3. 調用session.createQuery建立查詢對象
    1 Query query = session.createQuery(hql);
  4. 若是HQL語句包含參數則調用Query的setXxx設置參數
  5. 調用Query對象的list()或uniqueResult()執行查詢
    1 List<Student> list = query.list();

 

Criteria(條件查詢)

  Criteria查詢語句又叫QBC查詢(Query By Criteria)

  Criterion接口是Hibernate礦漿提供的一個面向對象的查詢接口

    Restrictions工廠類  -->Criterion對象

  使用Criteria對象查詢數據的幾個步驟:

    1. 得到Hibernate的Session對象
    2. 經過Session得到Criteria對象
    3. 使用Restrictious的靜態方法建立Criterion條件對象
    4. 向Criteria對象添加Criterion查詢條件
    5. 執行Criteria的list()或uniqueResult()得到結果
 1 Session session = sessionFactory.openSession();
 2 Transaction tanTransaction = session.beginTransaction(); 3 Criteria criteria = session.createCriteria(Student.class); 4 criteria.add(Restrictions.eq("name", "王五")); 5 List<Student> list = criteria.list(); 6 for(Student s : list){ 7  System.out.println(s); 8 } 9 tanTransaction.commit(); 10 session.close(); 11 sessionFactory.close();

 

hibernate關聯映射

  • 一對多(one to many):在"多"的一方,添加"一"的一方的主鍵做爲外鍵(學生和班級,在學生的一方添加外鍵(班級的主鍵)做爲屬於哪一個班級)
  • 多對一(many to one):
  • 一對一(one to one):在任意一方引入對方主鍵做爲外鍵,兩個主鍵成爲聯合主鍵
  • 多對多(many to many):產生中間關係表,引入兩張表的主鍵做爲外鍵,兩個主鍵成爲聯合主鍵

 

   ·反轉

  inverse屬性值爲false(默認),至關於兩端都能控制。在實際開發中,若是是一對多的關係,會將"一"的一方的inseverse設置爲true,即由"多"的一方來維護關係,若是是多對多的關係,隨意一方便可

  inverse只對<set>、<onetomany>、<manytomany>有效,對<manytoone>、<onetoone>無效。

 

    ·級聯

  cascade定義的是有關聯關係的對象之間的級聯關係

    • save-update:執行保存和更新操做時進行級聯操做
    • delete:執行刪除時進行級聯操做
    • delete-orphan
    • all:對全部操做進行級聯操做
    • all-delete-orphan
    • none:對全部操做不進行級聯操做

      ★當設置了cascade屬性部位none時,hibernate會自動持久化所關聯的對象

      ★cascade屬性的設置會帶來性能上的變更,需謹慎設置

 

Hibernate檢索方式

  1. 導航對象圖檢索方式(前提是必須在對象關係映射文件配置多對一關係)
    1 Classes classes = (Classes)session.get(Classe.class, 1);
    2 Set<Student> set = classes.getStudents();
  2. OID檢索方式(get()、load())
    1 Classes classes1 = (Classes)session.get(Classe.class, 1);
    2 Classes classes2 = (Classes)session.load(Classe.class, 1);
  3. QBC檢索方式
    1 //建立criteria對象
    2 Critria criteria = session.createCriteria(Student.class);
    3 //設置查詢條件
    4 Criterion criterion = Restrictious.eq("id", 1); 5 //添加查詢條件 6 criteria.add(criterion); 7 //執行查詢結果 8 List<Student> cs = criteria.list();
    HQL檢索方式(Hibernate Query Language)
  4. HQL檢索方式(Hibernate Query Language)
    1 [select/update/delete...][from][where...][group by...]
    2 [having...][order by...][asc/desc]
  5. 本地SQL檢索方式
    1 SQLQuery sqlQuery = session.creatSQLQuery("select id,name,age,city from customer");

 

投影查詢:用來查詢對象的部分屬性

 1 Configuration configuration = new Configuration().configure();
 2 SessionFactory sesionFactory = configuration.buildSessionFactory();
 3 Session session = sesionFactory.openSession();
 4 Transaction taTransaction = session.beginTransaction();
 5         
 6 String hql = "select p.id,p.name,p.description from Persion p";
 7 Query query = session.createQuery(hql);
 8 List<Object[]> list = query.list();
 9 Iterator iterator = list.iterator();
10 while (iterator.hasNext()) {
11     Object[] object = (Object[]) iterator.next();
12     System.out.println(object[0] + ", " + object[1]);
13 }
14 taTransaction.commit();
15 session.close();
16 sesionFactory.close();

 

動態實例查詢:

1 String hql = "select new Person(p.id,p.name,p.description) from Persion p";

    注:必須有構造方法和無參構造

 

條件查詢:

  1. 按參數位置查詢
    1         String hql = "from Customer where name like ?";
    2         Query query = session.createQuery(hql);
    3         query.setString(0, "%wy%");
    4         List<Customer> list = query.list();
    5 //        setDate()        給映射類型爲Date的參數賦值
    6 //        setDouble()        給映射類型爲double的參數賦值
    7 //        setBoolean()    給映射類型爲boolean的參數賦值
    8 //        setInteger()    給映射類型爲int的參數賦值
    9 //        setTime()        給映射類型爲date的參數賦值
  2. 按參數名稱查詢
    1         String hql = "from Customer where id=:id";
    2         Query query = session.createQuery(hql);
    3         query.setString("id", "1");
    4         List<Customer> list = query.list();    

     

分頁查詢:

  setFirstResult(int firstResult)

  setMaxResult(int maxResult)

 

  firstResult 默認值 0

  maxResult 默認值 所有

 

lazy(3個懶加載)

  須要數據的時候纔要加載

    一、類的懶加載(get()數據不存在則返回null,load()若是數據不存在,則報異常)

      

       session.load方法產生的是代理對象,該代理類是持久化類的子類

    二、集合的懶加載

       set的延遲加載:

             true

             false

             extra

         說明:

             一、由於延遲加載在映射文件設置,而映射文件一旦肯定,不能修改了。

             二、延遲加載是經過控制sql語句的發出時間來提升效率的

    三、manytoone的懶加載

       對於性能來講,沒有什麼影響,因此隨便怎麼樣都行

 

抓取策略

    

    join:左外鏈接

    select:默認的值

    subselect:子查詢

    (好比:根據需求分析,判斷出來該需求分析中含有子查詢,因此抓取策略應該用「subselect」)

 

    說明:

      一、由於抓取策略的設置在映射文件中,因此一旦映射文件生成就不能改變了。

      二、經過發出怎麼樣的SQL語句加載集合,從而優化效率的

 

 

一級緩存(生命週期和Session保持一致)

  • 一級緩存位置:  

  

    get():能夠把對象放入到一級緩存中,也能夠從一級緩存中把對象提取出來

    save():該方法能夠把一個對象放入到一級緩存中

    evit():能夠把一個對象從session的緩存中清空

    update():能夠把一個對象放入到一級緩存(session)中

    clear():清空一級緩存中全部的數據

    close():當調用session.close方法的時候,一級緩存的生命週期就結束了

  建立session的方式

分佈式緩存

一級緩存內存結構

 

二級緩存(二級緩存的生命週期和sessionFactory是一致的)

  • 實用場合

    公開的數據

       數據基本上不發生變化

       該數據保密性不是很強

    說明:若是一個數據一直在改變,不適合用緩存。

  • 設置二級緩存

   利用的是ehcache實現的二級緩存

      一、在hibernate的配置文件中

  二級緩存的供應商、開啓二級緩存:必須有!

 

    二級緩存的統計機制默認是關閉的,用來驗證save方法有沒有保存到二級緩存

 

    二、指定哪一個類(或者集合)開啓二級緩存(兩種方法) 

      第一種:在映射文件裏這麼寫:

       <class name="com.xjh.hibernate.domain.Classes">

        <cache usage="read-only"/>

      第二種:在hibernate.cfg.xml裏這麼寫:

        <class-cache usage="reand-only" class=""/>

 

  •  有哪些方法能夠把對象放入二級緩存中

    get方法,list方法能夠把一個或者一些對象放入到二級緩存中

 

  • 哪些方法能夠把對象從二級緩存中提取出來

    get方法,iterator方法能夠提取

 

查詢緩存

  

   一級緩存和二級緩存都是對象緩存:就是把該對象對應的數據庫表中的全部的字段所有查詢出來了,這種查詢在某些場合下會讓效率下降。例如:表中的字段特別多,可是程序中所須要的字段卻不多。

       查詢緩存也叫數據緩存:內存(頁面)中須要多少數據就把多少數據放入到查詢緩存中。

 

  • 生命週期

    只要一些數據放入到查詢緩存中,該緩存會一直存在,直到緩存中的數據被修改了,該緩存的生命週期就結束了。

 

  • 操做步驟

  1. 在hibernate的配置文件中,開啓查詢緩存

      

  2.使用查詢緩存

    

    

    

    

 

總結:

    

hibernate總共有三種緩存

    一級緩存解決的問題是在一次請求中,儘可能減小和數據庫交互的次數,在session.flush以前,改變的是一級緩存的對象的屬性。當session.flush的時候纔要跟數據庫交互,一級緩存解決不了重複查詢的問題。一級緩存是對象緩存。

    二級緩存能夠把常常不改變、經常使用的公共的數據放入進來,能夠重複查詢,利用get方法和iterator方法能夠把二級緩存中的數據獲得。二級緩存也是對象緩存。

    查詢緩存能夠緩存數據或者對象,能夠利用list方法把查詢緩存中的數據放入到緩存中。

    查詢緩存中存放的是數據,是數據緩存。

 

 

轉載請註明出處:http://www.cnblogs.com/Java-web-wy/

相關文章
相關標籤/搜索