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 }
運行結果: