Hibernate5筆記1--Hibernate簡介和第一個程序

Hibernate簡介:java

  Hibernate是一個開放源代碼的ORM(對象關係映射)框架,它對JDBC進行了很是輕量級的對象封裝,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。 Hibernate能夠應用在任何使用JDBC的場合,既能夠在Java的客戶端程序使用,也能夠在Servlet/JSP的Web應用中使用。 
                                                 ----  百度百科《Hibernate》 mysql

  實現持久化的方法:程序員

    (1)對象的序列化算法

      即實現了Serializable接口的類。適合於少許的對象進行暫時的持久化,適合於在網絡上傳輸對象。但不符合企業級應用的須要。由於企業應用中對數據的要求是大量的、長時間保存的、須要進行大規模查詢。sql

    (2)JDBC數據庫

      優勢:功能完備、從理論上說效率是最高的;能夠存儲海量的數據而且適合進行大規模檢索編程

      缺點:開發效率和維護效率低;開發難度大,代碼量大,佔到到總代碼量的1/3,或1/2緩存

    (3)ORM網絡

      ORM,即Object-Relational Mapping,對象關係映射。它是一種解決問題的思路,是一種思想。它的實質就是將關係數據庫中的業務數據用對象的形式表示出來,並經過面向對象的方式將這些對象組織起來,以實現系統業務邏輯。或者說,ORM就是內存中的對象與數據庫中的數據間的映射關係。session

              

      ORM的特色:開源的,實現了JDBC的封裝, 實現了簡單的API,輕量級解決方案,持久化對象是一個POJO類。最有名的ORM框架就是Hibernate。

  JPA框架:

    JPA,Java Persistence API,是Java EE 5的標準ORM接口。它是一種規範,一套接口,但不是實現。用於實現這一規範的ORM不少,其中Hibernate就是之一。

  JPA、ORM、Hibernare之間的關係:

    ORM是一種思想。JPA則是這種思想的具體的表現形式,是以Java語法規範表現出來的一種形式,是一套標準接口。Hibernate則是這套接口的具體實現。

  Hibernate5基本jar包:略

 

 

Hibernate第一個程序:

  1. Hibernate工做原理:

    

 

    其中hibernate.cfg.xml文件名不能更改,*.hbm.xml中的*,最好用對應的類名替代。

  2. 搭建Hibernate程序過程:

    (1) 定義持久化對象:

 1 package com.tongji.beans;
 2 
 3 public class Student {
 4     private Integer id; //定義實體的id要用Integer不能用int,由於底層要判斷id == null
 5     private String name;
 6     private int age;
 7     private double score;
 8     
 9     public Student() {
10         super();
11     }
12 
13     public Student(String name, int age, double score) {
14         super();
15         this.name = name;
16         this.age = age;
17         this.score = score;
18     }
19 
20     public Integer getId() {
21         return id;
22     }
23 
24     public void setId(Integer id) {
25         this.id = id;
26     }
27 
28     public String getName() {
29         return name;
30     }
31 
32     public void setName(String name) {
33         this.name = name;
34     }
35 
36     public int getAge() {
37         return age;
38     }
39 
40     public void setAge(int age) {
41         this.age = age;
42     }
43 
44     public double getScore() {
45         return score;
46     }
47 
48     public void setScore(double score) {
49         this.score = score;
50     }
51 
52     @Override
53     public String toString() {
54         return "Student [id=" + id + ", name=" + name + ", age=" + age + ", score=" + score + "]";
55     }
56     
57 }

    (2)配置映射文件(*.hbm.xml):

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5   
 6 <hibernate-mapping package="com.tongji.beans">
 7     <!-- 類到表的映射,屬性到字段的映射 -->
 8     <class name="Student" table="t_student">
 9         <id name="id" column="tid">
10             <generator class="native"/>
11         </id>
12         <property name="name" column="tname"/>
13         <property name="age" column="tage"/>
14         <property name="score" column="tscore"/>
15     </class>
16 </hibernate-mapping>

     其中,約束是在/org/hibernate/hibernate-mapping-3.0.dtd中查找。

     <class/>標籤:

        name屬性:指定持久化類。若<hibernate-mapping/>標籤設置了package屬性,那麼,此處的name屬性只需是類名便可;不然,須要是含包名的完整類名。
        table屬性:指定與持久化類對應的數據表的名稱。若不指定,Hibernate將默認爲表名與類名相同。
        catalog屬性:指定數據庫。默認爲主配置文件中指定的DB。

     <id/>與<property/>屬性:

        name屬性:指定持久化類的屬性名
        column屬性:指定數據表中與name屬性對應的字段名。若不指定,默認爲與name屬性同名。

        length屬性:指定屬性所映射字段的長度,單位字節。

        not-null屬性:爲指定字段添加非空約束。

        unique屬性:爲指定字段添加惟一性約束。

        type屬性:指定屬性所映射的字段的類型。若省略Hibernate會自動從持久化類中檢測到類型。這裏的類型取值支持兩類:Java類型與Hibernate類型。

          Java類型指的是Java代碼中的類型。如果基本數據類型,如int、double等,直接寫便可。但如果對象類型,則須要寫上全類名,如java.lang.String。

          Hibernate類型指的是Hibernate中定義的類型。在type的雙引號中Alt + ?可查看到Hibernate中的全部類型。

          sql-type屬性:固然映射文件中字段類型還支持一種類型,即數據庫中數據類型。但這種類型的使用,須要使用<column>元素,其中有一個sql-type屬性用於指定字段類型。其值爲所使用DBMS的數據類型。

         

       重點,Hibernate經常使用的內置主鍵生成策略:(即generator中的class選項)

        (1) increment生成策略:

          該策略是Hibernate本身在維護主鍵的值。當準備在數據庫表中插入一條新記錄時,首先從數據庫表中獲取當前主鍵字段的最大值,而後在最大值基礎上加1,做爲新插入記錄的主鍵值,這就是increment生成策略。
          用其生成的主鍵字段所對應的屬性類型能夠是long、short、int及其封裝類的類型。這種生成策略只有在沒有其餘進程向同一張表中插入數據時才能使用。在高併發下或集羣下不能使用

        (2) identity生成策略:

          該策略使用數據庫自身的自增加來維護主鍵值。如mysql使用auto_increment來維護。用其生成的主鍵字段所對應的屬性類型能夠是long、short、int及其封裝類的類型。
          該策略在生成主鍵值時會出現如下狀況:對於插入操做,即便最後的執行是回滾,DB中記錄主鍵值的變量也會增一。由於該生成策略在發生回滾以前已經調用過DB的主鍵自增,因此不管是否提交,對於DB來講已經執行

         (3) sequence生成策略:

          在Oracle、DB2和PostgreSQL等數據庫中建立一個序列(sequence),而後Hibernate經過該序列爲當前記錄獲取主鍵值,從而爲實體對象賦予主鍵字段映射屬性值。此即sequence生成策略,用其生成的主鍵字段映射屬性值的類型能夠是long、short、int及其封裝類的類型。  

          對於MySql數據庫,本來是不支持序列的。但稍做修改後,MySql也支持該生成策略。

        (4) native生成策略:

          由Hibernate根據所使用的數據庫支持能力從identity、sequence生成策略中選擇一種。 

          使用這種標識符屬性生成策略能夠根據不一樣的數據庫採用不一樣的生成策略,如Oracle中使用sequence,在MySQL中使用identity便於Hibernate應用在不一樣的數據庫之間移植

        (5) uuid生成策略:

          uuid生成策略採用UUID算法來生成一個字符串類型的主鍵值,該值使用IP地址、JVM的啓動時間(精確到1/4秒)、系統時間和一個計數器值(在當前的JVM中惟一)通過計算產生,能夠用於分佈式的Hibernate應用中。產生的標識符屬性是一個32位長度的字符串。使用這種生成策略,要求屬性的類型必須爲String類型
          這種標識符屬性生成策略生成的數值能夠保證多個數據庫之間的惟一性,而且因爲其生成與具體的數據庫沒有關係,因此其移植性較強。但因爲該值是32位長的字符串,因此佔用的數據庫空間較大,而且檢索速度較慢。不過,實際開發中使用這種生成策略較多
          除了使用Hibernate外,在JDBC中也可使用uuid生成主鍵。由於UUID是java.util包中的一個獨立的類。能夠打開項目的JRE System Library庫中的rt.jar,在其中找到java.util包,便可看到UUID這個類。

        (6) assigned生成策略:

          該生成策略的主鍵值來自於程序員的手工設置,即經過setId()方法設置。屬性類型能夠是整型,也能夠是String,但通常爲String。今生成策略,主要應用於業務相關主鍵。例如學號、身份證號作主鍵。

   (3) 配置主配置文件(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://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5     
 6 <hibernate-configuration>
 7     <session-factory>
 8         <!-- DB鏈接四要素 -->
 9         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
10         <property name="hibernate.connection.url">jdbc:mysql:///mytest?useSSL=false</property>
11         <property name="hibernate.connection.username">root</property>
12         <property name="hibernate.connection.password">248xiaohai</property>
13         <!-- 方言 -->
14         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
15         <!-- C3P0數據源 -->
16         <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
17         <!-- 當前Session上下文 -->
18         <property name="hibernate.current_session_context_class">thread</property>
19         <!-- 自動建表 -->
20         <property name="hibernate.hbm2ddl.auto">update</property>
21         <!-- 顯示SQL -->
22         <property name="hibernate.show_sql">true</property>
23         <!-- 格式化SQL -->
24         <property name="hibernate.format_sql">true</property>
25         
26         <!-- 註冊映射文件 -->
27         <mapping resource="com/tongji/beans/Student.hbm.xml"/>
28     </session-factory>
29 </hibernate-configuration>

     約束是在/org/hibernate/hibernate-configuration-3.0.dtd種查找的;

    DB鏈接四要素,同JDBC要求(數據庫鏈接的基本要求),注意兩點:

      在DB鏈接四要素中的name屬性名稱,connection.*hibernate.connection.*的效果是徹底相同的。是爲了兼容之前的版本;
      在數據庫鏈接的url屬性值的設置,通常寫法是jdbc:mysql://localhost:3306/test。但,localhost:3306不寫也是正確的,jdbc:mysql:///test

    方言,每一個數據庫管理系統都有本身的方言,每一個數據庫管理系統的不一樣版本也有本身的方言,選項在hibernate-core-5.0.1.Final.jar中的org.hibernate.dialect中查找

    C3P0數據源,數據源是指數據庫鏈接池,因爲進行數據庫鏈接比較耗時,系統就創建了一個數據路鏈接池,其中存放了必定數量的數據庫鏈接,方便須要操做數據庫時,直接從這個池中獲取數據庫鏈接。

      Hibernate5默認使用的是其本身開發的內置(built-in)鏈接池。該鏈接池只是讓調試代碼時使用,在真正產品中不能使用。工業生產中,經常使用的數據源有DBCP、C3P0等;

    當前Session上下文,指定緩存存放的位置,指定thread,表示將session放在每一個線程中;

    自動建表,有三個選項:

      create:每次加載主配置文件時都會刪除上一次的生成的表,而後再生成新表,哪怕兩次表結構沒有任何變化;

      update:第一次加載主配置文件時建立新表,以後的每次都是更新該表,當表字段增長時,會添加字段;當表字段減小時,不會減小字段。若表結構沒變化,但數據變化時,會修改數據;

      create-drop:每次加載主配置文件時會生成表,可是sessionFactory一旦關閉,表就自動刪除;

    註冊映射文件,前面配置的映射文件要在主配置文件中註冊,能夠有多個映射文件;

    顯示SQL、格式化SQL主要爲了調試,在執行Hibernate程序時,顯示底層自動生成的sql語句。

  (4) 定義測試類:

 1 package com.tongji.test;
 2 
 3 import org.hibernate.Session;
 4 import org.hibernate.SessionFactory;
 5 import org.hibernate.cfg.Configuration;
 6 import org.junit.Test;
 7 
 8 import com.tongji.beans.Student;
 9 
10 public class MyTest {
11     @Test
12     public void testSave() {
13         //1. 加載主配置文件
14         Configuration configure = new Configuration().configure();
15         //2. 建立Session工廠
16         SessionFactory SessionFactory = configure.buildSessionFactory();
17         //3. 獲取Session
18         Session session = SessionFactory.getCurrentSession();
19         try {
20             //4. 開啓事務
21             session.beginTransaction();
22             //session.getTransaction().begin();  一樣
23             //5. 操做
24             Student student = new Student("張三", 23, 93.5);
25             session.save(student);
26             //6. 事務提交
27             session.getTransaction().commit();
28         } catch (Exception e) {
29             e.printStackTrace();
30             //7. 事務回滾
31             session.getTransaction().rollback();
32         }
33     }
34 }

     注意:session的方法必須在事務以內執行,由於session是操做緩存中的數據,只有提交了事務以後,緩存中的數據才能寫到數據庫中。

相關文章
相關標籤/搜索