22-Java-Hibernate框架(二)

Hibernate的瞭解、Hibernate的搭建、Hibernate的基本使用流程等內容請閱讀21-Java-Hibernate(一)html

5、Hibernate的Query查詢接口(重中之重)java

  1.HQL語言瞭解:Hibernate Query Language(HQL),是hibernate的查詢語言,和SQL語句結構同樣,不一樣點注意點以下:mysql

      (1)HQL是面向對象查詢,SQL是面向結構查詢面試

      (2)在HQL使用類名和屬性名,替代了原有的表名和字段名  sql

      (3)在HQL語句中類型名和屬性名大小寫敏感  數據庫

      (4)若是須要select * 查詢全部字段的值,在HQL語句中能夠省略select *語句。例如:from User;緩存

      (5)若是須要join...on錶鏈接,須要創建關聯映射關係使用,不支持on子句session

      (6)不要使用數據庫提供的字符串函數、日期函數和一些特有的函數。一些基礎的函數可使用,例如:max(),min(),sum(),avg(),count()等。併發

      (7)若只查詢字體類中某幾個字段,返回的結果是泛型,值的集合app

  2.具體Query經常使用的相關接口看代碼演示

 1 package com.hibernatetest.test;
 2 
 3 import java.util.List;
 4 
 5 import org.hibernate.Query;
 6 import org.hibernate.Session;
 7 import com.hibernatetest.entity.User;
 8 import HibernatenateUtils.hibernateUtils;
 9 /*
10  * Query接口的經常使用方法:
11  *             1.setXXX():用於設置HQL語句中問號或變量的值
12  *             2.uniqueResult():獲得單個對象(返回Object類型),在已知查詢結果中只有一個或零個才能用此函數,如有多個知足條件的結果則報異常
13  *             3.executeUpdate():執行更新和刪除語句(返回int型做爲操做成功的次數)
14  *             4.分頁查詢
15  *             5.list():獲取結果集(返回List類型)
16  *             6.iterate():獲取結果集(返回Iterator類型)
17  * */
18 public class QueryTest {
19     public static void main(String[] args) {
20         //第一步:Query對象是經過Session獲取的,因此先要經過以前寫hibernate工具類獲取Session對象
21         Session    session = hibernateUtils.getSession();
22         
23         //第二步:CreateQuery("HQL語句"):用於建立Query對象。
24         Query query = session.createQuery("from User where uname='zhangsan'");
25         
26         /*查詢參數設值setXXX(): (兩種方式)
27          * 1.問號設值
28          *             Query query = session.createQuery("from User where uid between ? and ?");
29          *             query.setInteger(0,5);//給第一個問號處賦值5
30          *             query.setInteger(1,10);//給第一個問號處賦值10
31          *             
32          * 2.變量設值
33          *             Query query = session.createQuery("from User where uname=:name");
34          *             query.setString(name,"zhangsan");//給name變量賦值
35          * 
36          * 3.模糊查詢
37          *             Query query = session.createQuery("from User where uname likt %?%");錯!!!!!
38          *             Query query = session.createQuery("from User where uname like ?");對!!!!
39          *             query.setString(0,"%" +"zhang"+ "%");//給name變量賦值
40          * 
41          * 4.分頁查詢
42          *             Query query = session.createQuery("from User where uname='zhangsan'");
43          *             query.setFirstResult(0);從知足條件的數據中的第一條數據開始抓取
44          *             query.setMaxResult(2);從知足條件的數據中只抓取前兩條數據
45          * 
46          * 5.獲取單個對象
47          *             Query query = session.createQuery("select count(*) from User where uname='zhangsan'");
48          *             Object object = query.uniqueResult();
49          * 
50          * 6.構造查詢
51          *             Query query = session.createQuery("select new User(5,"zhangsan") from User where uname='zhangsan'");
52          *             Object object = query.uniqueResult();
53          * */
54         
55         /*數據庫更新和刪除操做executeUpdate()
56          * 1.刪除
57          *             Query query = session.createQuery("delete from User where uid in(1,6)");//刪除id爲1和6的數據,即便數據庫中沒有符合條件的數據也不會報錯
58          *             int execute = query.executeUpdate();//返回成功操做的次數
59          * */
60         
61         //第三步:Query獲取結果集
62         //1.list()獲取
63         List<?> list = query.list();
64         for(Object u:list){
65             User user = (User)u;
66             System.out.println(user);
67         }
68         /*2.iterate()獲取
69          * Iterator<?> iterator = query.iterate();
70          * while(iterator.hasNext()){
71          *        User user = (User)iterator.next();
72          *        System.out.println(user);
73          * }
74          * */
75         /*面試要考:list()和iterate()獲取結果集的區別:
76          * list():一次把全部數據從數據庫中取出來
77          * iterate():先從數據庫中查詢知足條件的id,若是緩存中包含所有要查詢的id的數據,就無需再查數據庫,直接從緩存中取數據,不然,根據id從數據庫中取
78          * */
79         
80         //第四步:記得將Session關閉
81         session.close();
82     }
83 }

6、Hibernate的三個狀態

    對象(持久化類的實例)處於session對象的管理中才能與數據庫發生聯繫。在Hibernate框架應用中,咱們依據對象對象與session對象的關係不一樣狀況,

  把對象的狀態分爲人的三種:瞬時狀態、遊離狀態、持久狀態。

    Transient(瞬時狀態|臨時狀態):在new以後,save()以前,數據庫沒有應用的數據

      若是對象未與session對象關聯過,咱們稱該對象處於瞬時狀態

    Persistent(持久狀態):在save()以後,在session關閉以前,數據庫有相對應的數據

      若是對象與session關聯起來了,且該對象對應到數據庫記錄,則稱該對象處於持久狀態

    

  三狀態結構圖:

          

  三狀態轉換關係:

      1.瞬時狀態轉換爲持久狀態:

          使用session的save()或saveOrUpdate()方法保存對象後,該對象的狀態由瞬時狀態轉換爲持久狀態

          使用session的get()或load()方法獲取對象後,該對象的狀態爲持久狀態

      2.持久狀態轉換爲瞬時狀態

          執行session對象的delete()方法後,對象由原來的持久狀態變爲瞬時狀態,所以該對象沒有與任何的數據庫數據有關聯

      3.持久狀態變爲遊離狀態

          執行session對象的evict()、clear()、close()方法,對象由原來的持久狀態變爲遊離狀態。

      4.遊離狀態變爲持久狀態

          從新獲取對象session對象,執行session對象的update()或saveOrUpdate方法,由遊離狀態轉換爲持久狀態,該對象再次與session關聯

      5.遊離狀態轉換爲瞬時狀態

          執行session的delete()方法,對象有遊離狀態變爲瞬時狀態

          對瞬時狀態或遊離狀態的對象再也不被其餘對象引用時,會被Java虛擬機按照垃圾回收機制處理

7、Hibernate根據實體自動構建生成表

  第一步:在hibernate.cfg.xml中添加<property name="hibernate.hbm2ddl.auto">update</property>,設置自動生成表

 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 
 8 <session-factory>
 9     <!--hibernate 方言 區分身份 -->
10     <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
11     <!-- 數據庫鏈接信息 -->
12     <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
13     <property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernatetest</property>
14     <property name="connection.username">root</property>
15     <property name="connection.password">root</property>
16 
17     <!-- hibernate自動生成表 update:若是數據庫不存在這張表自動建立一張表,若是存在不建立-->
18     <property name="hibernate.hbm2ddl.auto">update</property>
19     <!-- hibernate在控制檯顯示SQL語句 -->
20     <property name="show_sql">true</property>
21     <!-- hibernate格式化SQL,控制檯看起來更整齊 -->
22     <property name="format_sql">true</property>
23     <!-- 設置自動提交 -->
24     <property name="connection.autocommit">true</property>
25 
26     <!-- <property name="connection.characterEncoding">UTF-8</property> -->
27     <!--加載hibernate映射  -->
28     <mapping resource="com/hibernatetest/entity/Entity.hbm.xml" />
29 </session-factory>
30 
31 </hibernate-configuration>

  第二步:編寫實體類

  第三步:配置映射文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3                                    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <!-- name:對應的實體類的權限定名稱,table:對應數據庫表名稱 -->
 6  <class name="com.hibernatetest.entity.Entity" table="hibernateEntity">
 7      <!-- id標籤用於配置主鍵屬性
 8              name屬性:對應實體類中屬性名稱
 9              type屬性:能夠省略,若是省略默認實體類中屬性的對應類型
10       -->
11   <id name="userid" type="java.lang.Integer">
12           <!-- column用於設置對應數據庫表中字段名。不寫column標籤,數據庫中的字段名則和Entity類中的屬性名一致
13               name:數據庫表中的字段名
14               length:設置字段長度
15            -->
16           <column name="userid"></column>
17           <!-- generator用於設置主鍵生成策略
18                native:數據庫本地生成策略,適用於多個數據庫
19                sequence:序列(Oracle使用)
20                imcrement:主要mysql數據庫使用,適用於全部數據庫,先查詢出最大的id,在此基礎上+1,有可能出現併發的問題
21                uuid:生成32位,不會重複的主鍵,能夠達到真正的跨數據庫
22                foreign:一般在一對一關聯的時候使用
23                自增加:identity,適用於mysql,db2,sql server。
24            -->
25           <generator class="native"></generator>
26   </id>
27   
28   <!-- property標籤用於配置其餘屬性
29              name:對應實體類中屬性名稱
30              type:能夠省略,若是省略默認實體類中屬性的對應類型
31       -->
32   <property name="username" type="java.lang.String">
33            <column name="username" length="32"></column>
34   </property>
35   <property name="password" type="java.lang.String" >
36            <column name="password" length="32"></column>
37   </property>
38   
39  </class>
40  
41 </hibernate-mapping>

  第四步:編寫測試類測試

    控制檯顯示hibernate在數據庫沒找到hibernateEntity表

          

    因而它便會在數據庫自動生成一張表

          

8、Hibernate的關聯映射

     實體與實體之間有一對1、多對1、多對多的關係,Hibernate也所以須要對錶與表之間進行關聯映射配置。

     假設:有一張表爲Entity,表中有userid,username,password三個字段,另外一張表Grade,表中有gradeid,userid,grade。

     我如今經過userid查詢對應另外一張表中的grade(此處能夠理解爲多對一)。步驟以下:

      第一步:搭建Hibernate,配置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 
 8 <session-factory>
 9     <!--hibernate 方言 區分身份 -->
10     <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
11     <!-- 數據庫鏈接信息 -->
12     <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
13     <property name="connection.url">jdbc:mysql://127.0.0.1:3306/hibernatetest</property>
14     <property name="connection.username">root</property>
15     <property name="connection.password">root</property>
16 
17     <!-- hibernate自動生成表 update:若是數據庫不存在這張表自動建立一張表,若是存在不建立-->
18     <property name="hibernate.hbm2ddl.auto">update</property>
19     <!-- hibernate在控制檯顯示SQL語句 -->
20     <property name="show_sql">true</property>
21     <!-- hibernate格式化SQL,控制檯看起來更整齊 -->
22     <property name="format_sql">true</property>
23     <!-- 設置自動提交 -->
24     <property name="connection.autocommit">true</property>
25 
26     <!-- <property name="connection.characterEncoding">UTF-8</property> -->
27     
28     <!--加載hibernate映射文件  -->
29     <mapping resource="com/hibernatetest/entity/Entity.hbm.xml" />
30     <mapping resource="com/hibernate/grade/Grade.hbm.xml" />
31 </session-factory>
32 
33 </hibernate-configuration>

     第二步:配置兩張表對應的映射文件

Entity.hbm.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3                                    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <!-- name:對應的實體類的權限定名稱,table:對應數據庫表名稱 -->
 6  <class name="com.hibernatetest.entity.Entity" table="hibernateEntity">
 7      <!-- id標籤用於配置主鍵屬性
 8              name屬性:對應實體類中屬性名稱
 9              type屬性:能夠省略,若是省略默認實體類中屬性的對應類型
10       -->
11   <id name="userid" type="java.lang.Integer">
12           <!-- column用於設置對應數據庫表中字段名。不寫column標籤,數據庫中的字段名則和Entity類中的屬性名一致
13               name:數據庫表中的字段名
14               length:設置字段長度
15            -->
16           <column name="userid"></column>
17           <!-- generator用於設置主鍵生成策略
18                native:數據庫本地生成策略,適用於多個數據庫
19                sequence:序列(Oracle使用)
20                imcrement:主要mysql數據庫使用,適用於全部數據庫,先查詢出最大的id,在此基礎上+1,有可能出現併發的問題
21                uuid:生成32位,不會重複的主鍵,能夠達到真正的跨數據庫
22                foreign:一般在一對一關聯的時候使用
23                自增加:identity,適用於mysql,db2,sql server。
24            -->
25           <generator class="native"></generator>
26   </id>
27   
28   <!-- property標籤用於配置其餘屬性
29              name:對應實體類中屬性名稱
30              type:能夠省略,若是省略默認實體類中屬性的對應類型
31       -->
32   <property name="username" type="java.lang.String">
33            <column name="username" length="32"></column>
34   </property>
35   <property name="password" type="java.lang.String" >
36            <column name="password" length="32"></column>
37   </property>
38  </class>
39  
40 </hibernate-mapping>

Grade.hbm.xml:(此處須要加入對grade表的多對一的映射關係)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3                                    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <!-- name:對應的實體類的權限定名稱,table:對應數據庫表名稱 -->
 6  <class name="com.hibernate.grade.Grade" table="hibernateGrade">
 7      <!-- id標籤用於配置主鍵屬性
 8              name屬性:對應實體類中屬性名稱
 9              type屬性:能夠省略,若是省略默認實體類中屬性的對應類型
10       -->
11   <id name="gradeid" type="java.lang.Integer">
12           <!-- column用於設置對應數據庫表中字段名。不寫column標籤,數據庫中的字段名則和Entity類中的屬性名一致
13               name:數據庫表中的字段名
14               length:設置字段長度
15            -->
16           <column name="gradeid"></column>
17           <!-- generator用於設置主鍵生成策略
18                native:數據庫本地生成策略,適用於多個數據庫
19                sequence:序列(Oracle使用)
20                imcrement:主要mysql數據庫使用,適用於全部數據庫,先查詢出最大的id,在此基礎上+1,有可能出現併發的問題
21                uuid:生成32位,不會重複的主鍵,能夠達到真正的跨數據庫
22                foreign:一般在一對一關聯的時候使用
23                自增加:identity,適用於mysql,db2,sql server。
24            -->
25           <generator class="native"></generator>
26   </id>
27   
28   <!-- property標籤用於配置其餘屬性
29              name:對應實體類中屬性名稱
30              type:能夠省略,若是省略默認實體類中屬性的對應類型
31       -->
32       
33   <!-- 多對一映射關係 -->
34   <!-- name:當前Grade類的Entity屬性
35          column:Grade類的外鍵
36          fetch:有join和select.默認爲select
37                   select:查了當前表以後,再查外鍵所在的那張表
38                   join:在多對一將本來須要兩條sql語句以left outer join(左外鏈接)方式用一條語句解決
39          cascade:級聯操做關聯表:慎用
40                  save-update:在添加或操做的時候使用級聯操做關聯表
41                  delete:在刪除的時候使用級聯操做關聯表
42                  all:在全部操做的時候使用級聯操做關聯表
43                  none:任什麼時候候都不使用
44    -->
45   <many-to-one name="entity" column="userid" fetch="join"></many-to-one>
46   
47   <property name="grade" type="java.lang.Double" >
48            <column name="grade"></column>
49   </property>
50  </class>
51  
52 </hibernate-mapping>

      第三步:編寫兩張表對應的實體類

Entity類:

 1 package com.hibernatetest.entity;
 2 
 3 public class Entity {
 4     private Integer userid;
 5     private String username;
 6     private String password;
 7     public Entity() {
 8         super();
 9         // TODO Auto-generated constructor stub
10     }
11     public Entity(Integer userid, String username, String password) {
12         super();
13         this.userid = userid;
14         this.username = username;
15         this.password = password;
16     }
17     public Integer getUserid() {
18         return userid;
19     }
20     public void setUserid(Integer userid) {
21         this.userid = userid;
22     }
23     public String getUsername() {
24         return username;
25     }
26     public void setUsername(String username) {
27         this.username = username;
28     }
29     public String getPassword() {
30         return password;
31     }
32     public void setPassword(String password) {
33         this.password = password;
34     }
35     @Override
36     public int hashCode() {
37         final int prime = 31;
38         int result = 1;
39         result = prime * result
40                 + ((password == null) ? 0 : password.hashCode());
41         result = prime * result + ((userid == null) ? 0 : userid.hashCode());
42         result = prime * result
43                 + ((username == null) ? 0 : username.hashCode());
44         return result;
45     }
46     @Override
47     public boolean equals(Object obj) {
48         if (this == obj)
49             return true;
50         if (obj == null)
51             return false;
52         if (getClass() != obj.getClass())
53             return false;
54         Entity other = (Entity) obj;
55         if (password == null) {
56             if (other.password != null)
57                 return false;
58         } else if (!password.equals(other.password))
59             return false;
60         if (userid == null) {
61             if (other.userid != null)
62                 return false;
63         } else if (!userid.equals(other.userid))
64             return false;
65         if (username == null) {
66             if (other.username != null)
67                 return false;
68         } else if (!username.equals(other.username))
69             return false;
70         return true;
71     }
72     @Override
73     public String toString() {
74         return "Entity [userid=" + userid + ", username=" + username
75                 + ", password=" + password + "]";
76     }
77     
78 }

Grade類:

 1 package com.hibernate.grade;
 2 
 3 import com.hibernatetest.entity.Entity;
 4 
 5 public class Grade {
 6     private Integer gradeid;
 7     private Entity entity;
 8     private Double grade;
 9     public Grade() {
10         super();
11         // TODO Auto-generated constructor stub
12     }
13     public Grade(Integer gradeid, Entity entity, Double grade) {
14         super();
15         this.gradeid = gradeid;
16         this.entity = entity;
17         this.grade = grade;
18     }
19     public Integer getGradeid() {
20         return gradeid;
21     }
22     public void setGradeid(Integer gradeid) {
23         this.gradeid = gradeid;
24     }
25     public Entity getEntity() {
26         return entity;
27     }
28     public void setEntity(Entity entity) {
29         this.entity = entity;
30     }
31     public Double getGrade() {
32         return grade;
33     }
34     public void setGrade(Double grade) {
35         this.grade = grade;
36     }
37     @Override
38     public int hashCode() {
39         final int prime = 31;
40         int result = 1;
41         result = prime * result + ((entity == null) ? 0 : entity.hashCode());
42         result = prime * result + ((grade == null) ? 0 : grade.hashCode());
43         result = prime * result + ((gradeid == null) ? 0 : gradeid.hashCode());
44         return result;
45     }
46     @Override
47     public boolean equals(Object obj) {
48         if (this == obj)
49             return true;
50         if (obj == null)
51             return false;
52         if (getClass() != obj.getClass())
53             return false;
54         Grade other = (Grade) obj;
55         if (entity == null) {
56             if (other.entity != null)
57                 return false;
58         } else if (!entity.equals(other.entity))
59             return false;
60         if (grade == null) {
61             if (other.grade != null)
62                 return false;
63         } else if (!grade.equals(other.grade))
64             return false;
65         if (gradeid == null) {
66             if (other.gradeid != null)
67                 return false;
68         } else if (!gradeid.equals(other.gradeid))
69             return false;
70         return true;
71     }
72     @Override
73     public String toString() {
74         return "Grade [gradeid=" + gradeid + ", entity=" + entity + ", grade="
75                 + grade + "]";
76     }
77     
78 }

      第四步:編寫HibernateUtils工具類和測試類

測試類:

 1 package Hibernatetest; 4 
 5 import org.hibernate.Query;
 6 import org.hibernate.Session;
 7 import org.hibernate.Transaction;
 8 
 9 import com.hibernate.grade.Grade;
10 import com.hibernatetest.entity.Entity;
11 
12 import HibernatenateUtils.hibernateUtils;
13 
14 public class annotationtest {
15     
16     public void test(){
17         
18     }
19     public static void main(String[] args) {
20         Session session = hibernateUtils.getSession();
21         
22         //先製造兩條記錄在數據庫中
23         Transaction transaction = session.beginTransaction();
24         Entity user1 = new Entity(null,"zhangsan","1111");
25         Grade grade1 = new Grade(null,user1,Double.valueOf(85));
26         session.save(user1);
27         session.save(grade1);
28         transaction.commit();
29         
30         transaction = session.beginTransaction();
31         Entity user2 = new Entity(null,"lisi","2222");
32         Grade grade2 = new Grade(null,user2,Double.valueOf(100));
33         session.save(user2);
34         session.save(grade2);
35         transaction.commit();
36         
37         //查詢測試
38         Grade grade = session.get(Grade.class,3);
39         System.out.println(grade);
40         session.close();
41     }
42 }

運行結果:

    

相關文章
相關標籤/搜索