1. 程式人生 > >學習Hibernate5 JPA這一篇就夠了

學習Hibernate5 JPA這一篇就夠了

**配套資料,免費下載** 連結:https://pan.baidu.com/s/158JkczSacADez-fEMDXSYQ 提取碼:2ce1 複製這段內容後開啟百度網盤手機App,操作更方便哦 ## 第一章 Hibernate5 JPA快速入門 ### 1.1、Hibernate5 JPA概述 JPA的全稱是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基於ORM的規範,內部是由一系列的介面和抽象類構成。JPA通過JDK 5.0註解描述物件-關係表的對映關係,並將執行期的實體物件持久化到資料庫中 ![fd5e9c1f88bcdb6c41f6685998b44e0f068.jpg](https://gitee.com/caochenlei/BlogImages/raw/master/20200808110321.jpg) 但是JPA僅僅只是一套介面規範和抽象類,並不能真正的去幹活,因此,就有很多廠商實現了JPA的規範,提供了相應的技術支援,就類似實現了JDBC的MySQL驅動,而本節課程將採用Hibernate實現作為驅動使用,因此我稱之為Hibernate5 JPA ### 1.2、Hibernate5 JPA下載 官方網址:[hibernate orm](http://hibernate.org/orm/) 目錄介紹: hibernate-release-5.0.7.Final資料夾介紹: ![image-20200804215450351](https://gitee.com/caochenlei/BlogImages/raw/master/20200804215452.png) hibernate-release-5.0.7.Final\lib資料夾介紹: ![image-20200808110712846](https://gitee.com/caochenlei/BlogImages/raw/master/20200808110713.png) ### 1.3、Hibernate5 JPA工程搭建 前邊學習的Hibernate,接下來進行工程搭建,根Hibernate相比,它只需要再多加入一個包就行 把下面四個資料夾的內容全部拷貝到lib中 - hibernate-release-5.0.7.Final\lib\required ![image-20200804232427671](https://gitee.com/caochenlei/BlogImages/raw/master/20200804232428.png) - hibernate-release-5.0.7.Final\lib\optional\c3p0 ![image-20200804231638012](https://gitee.com/caochenlei/BlogImages/raw/master/20200804231639.png) - **hibernate-release-5.0.7.Final\lib\jpa** ![image-20200808105905572](https://gitee.com/caochenlei/BlogImages/raw/master/20200808105907.png) - 日誌記錄包 ![image-20200804232406439](https://gitee.com/caochenlei/BlogImages/raw/master/20200804232407.png) - 資料庫驅動 ![image-20200805105713238](https://gitee.com/caochenlei/BlogImages/raw/master/20200805105714.png) 把下面五個資料夾的內容全部拷貝到lib中後,全部選中,右鍵Build Path一下 ![image-20200808111218855](https://gitee.com/caochenlei/BlogImages/raw/master/20200808111222.png) Java工程搭建好了以後,我們需要有一個數據庫(hibernate_jpa)和兩張表用於測試: crm_cst_customer(客戶表) ```mysql CREATE TABLE `cst_customer` ( `cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客戶編號(主鍵)', `cust_name` VARCHAR(32) DEFAULT NULL COMMENT '客戶名稱', `cust_source` VARCHAR(32) DEFAULT NULL COMMENT '客戶資訊來源', `cust_industry` VARCHAR(32) DEFAULT NULL COMMENT '客戶所屬行業', `cust_level` VARCHAR(32) DEFAULT NULL COMMENT '客戶級別', `cust_phone` VARCHAR(64) DEFAULT NULL COMMENT '固定電話', `cust_mobile` VARCHAR(16) DEFAULT NULL COMMENT '行動電話', PRIMARY KEY (`cust_id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ``` crm_cst_linkman(聯絡人表) ```mysql CREATE TABLE `cst_linkman` ( `lkm_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '聯絡人編號(主鍵)', `lkm_name` VARCHAR(16) DEFAULT NULL COMMENT '聯絡人姓名', `lkm_gender` CHAR(1) DEFAULT NULL COMMENT '聯絡人性別', `lkm_phone` VARCHAR(16) DEFAULT NULL COMMENT '聯絡人辦公電話', `lkm_mobile` VARCHAR(16) DEFAULT NULL COMMENT '聯絡人手機', `lkm_email` VARCHAR(64) DEFAULT NULL COMMENT '聯絡人郵箱', `lkm_qq` VARCHAR(16) DEFAULT NULL COMMENT '聯絡人qq', `lkm_position` VARCHAR(16) DEFAULT NULL COMMENT '聯絡人職位', `lkm_memo` VARCHAR(512) DEFAULT NULL COMMENT '聯絡人備註', `lkm_cust_id` BIGINT(32) NOT NULL COMMENT '客戶id', PRIMARY KEY (`lkm_id`), KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`), CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ``` 在Java工程的src路徑下建立一個名為META-INF的資料夾,在此資料夾下建立一個名為persistence.xml的配置檔案 通用配置檔案(掌握): persistence.xml(全路徑:/hibernate_jpa/src/META-INF/persistence.xml) ```xml org.hibernate.jpa.HibernatePersistenceProvider ``` 整合C3P0連線池版本配置檔案(瞭解): ```xml org.hibernate.jpa.HibernatePersistenceProvider
``` 對於本節課程來說,使用哪一個都可以,但是第一個更通用,更簡單,我們採用第一個,配置檔案有了以後,我們需要編寫實體類跟資料庫表的對映關係 Customer.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/Customer.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; /** * @Entity :宣告是一個實體類 * @Table :配置實體類和表的對映關係 * * name :配置資料庫表的名稱 */ @Entity @Table(name = "cst_customer") public class Customer { /** * @Id :宣告主鍵的配置 * @GeneratedValue :配置主鍵的生成策略 * strategy: * GenerationType.IDENTITY :自增(底層資料庫必須支援自動增長),mysql * GenerationType.SEQUENCE :序列(底層資料庫必須支援序列),oracle * GenerationType.TABLE :JPA提供的一種機制,通過一張資料庫表的形式幫助我們完成主鍵自增 * GenerationType.AUTO :由程式自動的幫助我們選擇主鍵生成策略 * @Column :配置屬性和欄位的對映關係 * name :資料庫表中欄位的名稱 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "cust_id") private Long custId; @Column(name = "cust_name") private String custName; @Column(name = "cust_source") private String custSource; @Column(name = "cust_industry") private String custIndustry; @Column(name = "cust_level") private String custLevel; @Column(name = "cust_phone") private String custPhone; @Column(name = "cust_mobile") private String custMobile; public Long getCustId() { return custId; } public void setCustId(Long custId) { this.custId = custId; } public String getCustName() { return custName; } public void setCustName(String custName) { this.custName = custName; } public String getCustSource() { return custSource; } public void setCustSource(String custSource) { this.custSource = custSource; } public String getCustIndustry() { return custIndustry; } public void setCustIndustry(String custIndustry) { this.custIndustry = custIndustry; } public String getCustLevel() { return custLevel; } public void setCustLevel(String custLevel) { this.custLevel = custLevel; } public String getCustPhone() { return custPhone; } public void setCustPhone(String custPhone) { this.custPhone = custPhone; } public String getCustMobile() { return custMobile; } public void setCustMobile(String custMobile) { this.custMobile = custMobile; } @Override public String toString() { return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource + ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custPhone=" + custPhone + ", custMobile=" + custMobile + "]"; } } ``` LinkMan.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/LinkMan.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "cst_linkman") public class LinkMan { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "lkm_id") private Long lkmId; @Column(name = "lkm_name") private String lkmName; @Column(name = "lkm_gender") private String lkmGender; @Column(name = "lkm_phone") private String lkmPhone; @Column(name = "lkm_mobile") private String lkmMobile; @Column(name = "lkm_email") private String lkmEmail; @Column(name = "lkm_qq") private String lkmQq; @Column(name = "lkm_position") private String lkmPosition; @Column(name = "lkm_memo") private String lkmMemo; public Long getLkmId() { return lkmId; } public void setLkmId(Long lkmId) { this.lkmId = lkmId; } public String getLkmName() { return lkmName; } public void setLkmName(String lkmName) { this.lkmName = lkmName; } public String getLkmGender() { return lkmGender; } public void setLkmGender(String lkmGender) { this.lkmGender = lkmGender; } public String getLkmPhone() { return lkmPhone; } public void setLkmPhone(String lkmPhone) { this.lkmPhone = lkmPhone; } public String getLkmMobile() { return lkmMobile; } public void setLkmMobile(String lkmMobile) { this.lkmMobile = lkmMobile; } public String getLkmEmail() { return lkmEmail; } public void setLkmEmail(String lkmEmail) { this.lkmEmail = lkmEmail; } public String getLkmQq() { return lkmQq; } public void setLkmQq(String lkmQq) { this.lkmQq = lkmQq; } public String getLkmPosition() { return lkmPosition; } public void setLkmPosition(String lkmPosition) { this.lkmPosition = lkmPosition; } public String getLkmMemo() { return lkmMemo; } public void setLkmMemo(String lkmMemo) { this.lkmMemo = lkmMemo; } @Override public String toString() { return "LinkMan [lkmId=" + lkmId + ", lkmName=" + lkmName + ", lkmGender=" + lkmGender + ", lkmPhone=" + lkmPhone + ", lkmMobile=" + lkmMobile + ", lkmEmail=" + lkmEmail + ", lkmQq=" + lkmQq + ", lkmPosition=" + lkmPosition + ", lkmMemo=" + lkmMemo + "]"; } } ``` ### 1.4、Hibernate5 JPA增刪改查 CustomerJPATest.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/CustomerJPATest.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import org.junit.Test; public class CustomerJPATest { /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存操作 */ @Test public void testSave() { // 獲取實體管理器工廠 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); // 獲取實體管理器 EntityManager entityManager = entityManagerFactory.createEntityManager(); // 獲取事務 EntityTransaction transaction = entityManager.getTransaction(); // 開啟事務 transaction.begin(); // 建立實體物件並儲存 Customer customer1 = new Customer(); customer1.setCustName("張三"); entityManager.persist(customer1); Customer customer2 = new Customer(); customer2.setCustName("李四"); entityManager.persist(customer2); Customer customer3 = new Customer(); customer3.setCustName("王五"); entityManager.persist(customer3); // 提交事務 transaction.commit(); // 釋放資源 entityManager.close(); entityManagerFactory.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 立即查詢操作 */ @Test public void testQuery1() { // 獲取實體管理器工廠 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); // 獲取實體管理器 EntityManager entityManager = entityManagerFactory.createEntityManager(); // 獲取事務 EntityTransaction transaction = entityManager.getTransaction(); // 開啟事務 transaction.begin(); // 查詢實體並輸出 Customer customer = entityManager.find(Customer.class, 2L); System.out.println(customer); // 提交事務 transaction.commit(); // 釋放資源 entityManager.close(); entityManagerFactory.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 延遲查詢操作 */ @Test public void testQuery2() { // 獲取實體管理器工廠 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); // 獲取實體管理器 EntityManager entityManager = entityManagerFactory.createEntityManager(); // 獲取事務 EntityTransaction transaction = entityManager.getTransaction(); // 開啟事務 transaction.begin(); // 查詢實體並輸出 Customer customer = entityManager.getReference(Customer.class, 2L); System.out.println(customer); // 提交事務 transaction.commit(); // 釋放資源 entityManager.close(); entityManagerFactory.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除操作 */ @Test public void testDelete() { // 獲取實體管理器工廠 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); // 獲取實體管理器 EntityManager entityManager = entityManagerFactory.createEntityManager(); // 獲取事務 EntityTransaction transaction = entityManager.getTransaction(); // 開啟事務 transaction.begin(); // 查詢實體並刪除 Customer customer = entityManager.find(Customer.class, 1L); entityManager.remove(customer); // 提交事務 transaction.commit(); // 釋放資源 entityManager.close(); entityManagerFactory.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 更新操作 */ @Test public void testUpdate() { // 獲取實體管理器工廠 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); // 獲取實體管理器 EntityManager entityManager = entityManagerFactory.createEntityManager(); // 獲取事務 EntityTransaction transaction = entityManager.getTransaction(); // 開啟事務 transaction.begin(); // 查詢實體並更新 Customer customer = entityManager.find(Customer.class, 2L); customer.setCustSource("電視廣告"); entityManager.merge(customer); // 提交事務 transaction.commit(); // 釋放資源 entityManager.close(); entityManagerFactory.close(); } } ``` ### 1.5、Hibernate5 JPA工具類 JPAUtil.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/JPAUtil.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class JPAUtil { private static EntityManagerFactory entityManagerFactory; static { entityManagerFactory = Persistence.createEntityManagerFactory("myJpa"); } public static EntityManager getEntityManager() { return entityManagerFactory.createEntityManager(); } } ``` ## 第二章 Hibernate5 JPA核心物件 ### 2.1、Persistence Persistence物件主要作用是用於獲取EntityManagerFactory物件的 。通過呼叫該類的createEntityManagerFactory靜態方法,根據配置檔案中持久化單元名稱建立EntityManagerFactory。 ### 2.2、EntityManagerFactory EntityManagerFactory 介面主要用來建立 EntityManager 例項。 ### 2.3、EntityManager 在 JPA 規範中,EntityManager是完成持久化操作的核心物件。實體類作為普通 java物件,只有在呼叫 EntityManager將其持久化後才會變成持久化物件。EntityManager物件在一組實體類與底層資料來源之間進行 O/R 對映的管理。它可以用來管理和更新 Entity Bean,根椐主鍵查詢 Entity Bean, 還可以通過JPQL語句查詢實體。我們可以通過呼叫EntityManager的方法完成獲取事務,以及持久化資料庫的操作,例如: - getTransaction:獲取事務物件 - persist:儲存操作 - merge:更新操作 - remove:刪除操作 - find/getReference:根據id查詢 ### 2.4、EntityTransaction 在 JPA 規範中,EntityTransaction是完成事務操作的核心物件,對於EntityTransaction在我們的Java程式碼中承接的功能比較簡單。 - begin:開啟事務 - commit:提交事務 - rollback:回滾事務 ## 第三章 Hibernate5 JPA對映配置 ![image-20200806220635419](https://gitee.com/caochenlei/BlogImages/raw/master/20200808125605.png) ### 3.1、一對多關聯 #### 3.1.1、修改實體 修改Customer.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/Customer.java) 在toString方法的下面新增多的集合 ```java /** * 一對多:一的一方配置多的集合 * @OneToMany :對映一對多 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * * mappedBy :放棄外來鍵維護 */ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "customer") private Set linkMans = new HashSet(); public Set getLinkMans() { return linkMans; } public void setLinkMans(Set linkMans) { this.linkMans = linkMans; } ``` 修改LinkMan.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/LinkMan.java) 在toString方法的下面新增一的物件 ```java /** * 多對一:多的一方配置一的物件 * @ManyToOne :對映多對一 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * @JoinColumn :設定兩張表之間外來鍵列 * name ;外來鍵的名稱 */ @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "lkm_cust_id") private Customer customer = new Customer(); public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } ``` #### 3.1.2、測試程式碼 OneToManyTest.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/OneToManyTest.java) ```java package com.caochenlei.hibernate.jpa; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import org.junit.Test; public class OneToManyTest { /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存客戶級聯儲存聯絡人 */ @Test public void test1() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個客戶 Customer customer1 = new Customer(); customer1.setCustName("張三"); Customer customer2 = new Customer(); customer2.setCustName("李四"); // 建立三個聯絡人 LinkMan linkMan1 = new LinkMan(); linkMan1.setLkmName("鳳姐"); LinkMan linkMan2 = new LinkMan(); linkMan2.setLkmName("如花"); LinkMan linkMan3 = new LinkMan(); linkMan3.setLkmName("旺財"); customer1.getLinkMans().add(linkMan1); customer1.getLinkMans().add(linkMan2); customer2.getLinkMans().add(linkMan3); linkMan1.setCustomer(customer1); linkMan2.setCustomer(customer1); linkMan3.setCustomer(customer2); entityManager.persist(customer1); entityManager.persist(customer2); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存聯絡人級聯儲存客戶 */ @Test public void test2() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個客戶 Customer customer1 = new Customer(); customer1.setCustName("張三"); Customer customer2 = new Customer(); customer2.setCustName("李四"); // 建立三個聯絡人 LinkMan linkMan1 = new LinkMan(); linkMan1.setLkmName("鳳姐"); LinkMan linkMan2 = new LinkMan(); linkMan2.setLkmName("如花"); LinkMan linkMan3 = new LinkMan(); linkMan3.setLkmName("旺財"); customer1.getLinkMans().add(linkMan1); customer1.getLinkMans().add(linkMan2); customer2.getLinkMans().add(linkMan3); linkMan1.setCustomer(customer1); linkMan2.setCustomer(customer1); linkMan3.setCustomer(customer2); entityManager.persist(linkMan1); entityManager.persist(linkMan2); entityManager.persist(linkMan3); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢客戶級聯查詢聯絡人 */ @Test public void test3() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Customer customer = entityManager.find(Customer.class, 1L); System.out.println(customer); Set linkMans = customer.getLinkMans(); for (LinkMan linkMan : linkMans) { System.out.println(linkMan); } transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢聯絡人級聯查詢客戶 */ @Test public void test4() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); LinkMan linkMan = entityManager.find(LinkMan.class, 1L); System.out.println(linkMan); Customer customer = linkMan.getCustomer(); System.out.println(customer); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 修改客戶、修改聯絡人,儲存客戶級聯儲存聯絡人 */ @Test public void test5() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Customer customer = entityManager.find(Customer.class, 1L); customer.setCustSource("電視廣告"); Set linkMans = customer.getLinkMans(); for (LinkMan linkMan : linkMans) { linkMan.setLkmMobile("15633029014"); } entityManager.persist(customer); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 修改客戶、修改聯絡人,儲存聯絡人級聯儲存客戶 */ @Test public void test6() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); LinkMan linkMan = entityManager.find(LinkMan.class, 1L); linkMan.setLkmMobile("110"); Customer customer = linkMan.getCustomer(); customer.setCustMobile("110"); entityManager.persist(linkMan); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除客戶級聯刪除聯絡人 */ @Test public void test7() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Customer customer = entityManager.find(Customer.class, 1L); entityManager.remove(customer); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除聯絡人級聯刪除客戶 */ @Test public void test8() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); LinkMan linkMan = entityManager.find(LinkMan.class, 3L); entityManager.remove(linkMan); transaction.commit(); entityManager.close(); } } ``` ### 3.2、多對多關聯 ![image-20200806230944798](https://gitee.com/caochenlei/BlogImages/raw/master/20200808141115.png) sys_user(使用者表) ```mysql CREATE TABLE `sys_user` ( `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '使用者id', `user_code` varchar(32) DEFAULT NULL COMMENT '使用者賬號', `user_name` varchar(64) DEFAULT NULL COMMENT '使用者名稱稱', `user_password` varchar(32) DEFAULT NULL COMMENT '使用者密碼', `user_state` char(1) DEFAULT NULL COMMENT '使用者狀態', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` sys_role(角色表) ```mysql CREATE TABLE `sys_role` ( `role_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '角色id', `role_name` varchar(32) DEFAULT NULL COMMENT '角色名稱', `role_memo` varchar(128) DEFAULT NULL COMMENT '角色備註', PRIMARY KEY (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` sys_user_role(中間表) ```mysql CREATE TABLE `sys_user_role` ( `role_id` bigint(32) NOT NULL COMMENT '角色id', `user_id` bigint(32) NOT NULL COMMENT '使用者id', PRIMARY KEY (`role_id`,`user_id`), KEY `FK_user_role_user_id` (`user_id`), CONSTRAINT `FK_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `FK_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` #### 3.2.1、建立實體 User.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/User.java) ```java package com.caochenlei.hibernate.jpa; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name = "sys_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long userId; @Column(name = "user_code") private String userCode; @Column(name = "user_name") private String userName; @Column(name = "user_password") private String userPassword; @Column(name = "user_state") private String userState; public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public String getUserState() { return userState; } public void setUserState(String userState) { this.userState = userState; } @Override public String toString() { return "User [userId=" + userId + ", userCode=" + userCode + ", userName=" + userName + ", userPassword=" + userPassword + ", userState=" + userState + "]"; } /** * 多對多:另一方的集合物件 * @ManyToMany :對映多對多 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * @JoinTable :用於對應中間表的設定 * * name :中間表名稱 * * joinColumns :設定中間表與本表關聯的外來鍵 * * inverseJoinColumns:設定中間表與關聯表對應的外來鍵 */ @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinTable(name = "sys_user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set roles = new HashSet(); public Set getRoles() { return roles; } public void setRoles(Set roles) { this.roles = roles; } } ``` Role.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/Role.java) ```java package com.caochenlei.hibernate.jpa; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name = "sys_role") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "role_id") private Long roleId; @Column(name = "role_name") private String roleName; @Column(name = "role_memo") private String roleMemo; public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleMemo() { return roleMemo; } public void setRoleMemo(String roleMemo) { this.roleMemo = roleMemo; } @Override public String toString() { return "Role [roleId=" + roleId + ", roleName=" + roleName + ", roleMemo=" + roleMemo + "]"; } /** * 多對多:另一方的集合物件 * @ManyToMany :對映多對多 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * * mappedBy :放棄外來鍵維護 */ @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "roles") private Set users = new HashSet(); public Set getUsers() { return users; } public void setUsers(Set users) { this.users = users; } } ``` #### 3.2.2、測試程式碼 ManyToManyTest.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/ManyToManyTest.java) ```java package com.caochenlei.hibernate.jpa; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import org.junit.Test; public class ManyToManyTest { /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存使用者級聯儲存角色 */ @Test public void test1() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個使用者 User user1 = new User(); user1.setUserName("曹晨磊"); User user2 = new User(); user2.setUserName("曹晨旭"); // 建立三個角色 Role role1 = new Role(); role1.setRoleName("呂布"); Role role2 = new Role(); role2.setRoleName("東皇"); Role role3 = new Role(); role3.setRoleName("趙雲"); user1.getRoles().add(role1); user1.getRoles().add(role2); user2.getRoles().add(role3); role1.getUsers().add(user1); role2.getUsers().add(user1); role3.getUsers().add(user2); entityManager.persist(user1); entityManager.persist(user2); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存角色級聯儲存使用者 */ @Test public void test2() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個使用者 User user1 = new User(); user1.setUserName("曹晨磊"); User user2 = new User(); user2.setUserName("曹晨旭"); // 建立三個角色 Role role1 = new Role(); role1.setRoleName("呂布"); Role role2 = new Role(); role2.setRoleName("東皇"); Role role3 = new Role(); role3.setRoleName("趙雲"); user1.getRoles().add(role1); user1.getRoles().add(role2); user2.getRoles().add(role3); role1.getUsers().add(user1); role2.getUsers().add(user1); role3.getUsers().add(user2); entityManager.persist(role1); entityManager.persist(role2); entityManager.persist(role3); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢使用者級聯查詢角色 */ @Test public void test3() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); User user = entityManager.find(User.class, 1L); System.out.println(user); Set roles = user.getRoles(); for (Role role : roles) { System.out.println(role); } transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢角色級聯查詢使用者 */ @Test public void test4() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Role role = entityManager.find(Role.class, 3L); System.out.println(role); Set users = role.getUsers(); for (User user : users) { System.out.println(user); } transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 修改使用者、修改角色,更新使用者級聯更新角色 */ @Test public void test5() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); User user = entityManager.find(User.class, 1L); user.setUserPassword("123456"); Set roles = user.getRoles(); for (Role role : roles) { role.setRoleMemo("123456"); } entityManager.merge(user); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 修改使用者、修改角色,更新角色級聯更新使用者 */ @Test public void test6() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Role role = entityManager.find(Role.class, 3L); role.setRoleMemo("123456"); Set users = role.getUsers(); for (User user : users) { user.setUserPassword("123456"); } entityManager.merge(role); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除使用者級聯刪除角色 */ @Test public void test7() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); User user = entityManager.find(User.class, 1L); entityManager.remove(user); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除角色級聯刪除使用者 */ @Test public void test8() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Role role = entityManager.find(Role.class, 3L); entityManager.remove(role); transaction.commit(); entityManager.close(); } } ``` ### 3.3、一對一關聯 ![image-20200808154248502](https://gitee.com/caochenlei/BlogImages/raw/master/20200808154251.png) student_base_info(學生資訊基本表) ```mysql CREATE TABLE `student_base_info` ( `stu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '學生id', `stu_name` varchar(20) DEFAULT NULL COMMENT '學生姓名', `stu_sex` varchar(20) DEFAULT NULL COMMENT '學生性別', PRIMARY KEY (`stu_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` student_other_info(學生資訊拓展表) ```mysql CREATE TABLE `student_other_info` ( `stu_id` bigint(20) NOT NULL COMMENT '學生id', `stu_img` varchar(255) DEFAULT NULL COMMENT '學生頭像', `stu_address` varchar(255) DEFAULT NULL COMMENT '學生地址', PRIMARY KEY (`stu_id`), CONSTRAINT `FK_stu_id` FOREIGN KEY (`stu_id`) REFERENCES `student_base_info` (`stu_id`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ``` #### 3.3.1、建立實體 StuBaseInfo.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/StuBaseInfo.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name = "student_base_info") public class StuBaseInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "stu_id") private Long stuId; @Column(name = "stu_name") private String stuName; @Column(name = "stu_sex") private String stuSex; public Long getStuId() { return stuId; } public void setStuId(Long stuId) { this.stuId = stuId; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getStuSex() { return stuSex; } public void setStuSex(String stuSex) { this.stuSex = stuSex; } @Override public String toString() { return "StuBaseInfo [stuId=" + stuId + ", stuName=" + stuName + ", stuSex=" + stuSex + "]"; } /** * 一對一:另一方的物件 * @OneToOne :對映一對一 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * * mappedBy :放棄外來鍵維護 */ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "stuBaseInfo") private StuOtherInfo stuOtherInfo; public StuOtherInfo getStuOtherInfo() { return stuOtherInfo; } public void setStuOtherInfo(StuOtherInfo stuOtherInfo) { this.stuOtherInfo = stuOtherInfo; } } ``` StuOtherInfo.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/StuOtherInfo.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name = "student_other_info") public class StuOtherInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "stu_id") private Long stuId; @Column(name = "stu_img") private String stuImg; @Column(name = "stu_address") private String stuAddress; public Long getStuId() { return stuId; } public void setStuId(Long stuId) { this.stuId = stuId; } public String getStuImg() { return stuImg; } public void setStuImg(String stuImg) { this.stuImg = stuImg; } public String getStuAddress() { return stuAddress; } public void setStuAddress(String stuAddress) { this.stuAddress = stuAddress; } @Override public String toString() { return "StuOtherInfo [stuId=" + stuId + ", stuImg=" + stuImg + ", stuAddress=" + stuAddress + "]"; } /** * 一對一:另一方的物件 * @OneToOne :對映一對一 * * fetch :抓取策略 * FetchType.LAZY :延遲載入(預設) * FetchType.EAGER :迫切查詢(多表連線查詢) * * cascade :級聯操作 * CascadeType.PERSIST :級聯儲存 * CascadeType.MERGE :級聯更新 * CascadeType.REMOVE :級聯刪除 * CascadeType.ALL :全部支援 * @JoinColumn :設定兩張表之間外來鍵列 * name ;外來鍵的名稱 */ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "stu_id") private StuBaseInfo stuBaseInfo ; public StuBaseInfo getStuBaseInfo() { return stuBaseInfo; } public void setStuBaseInfo(StuBaseInfo stuBaseInfo) { this.stuBaseInfo = stuBaseInfo; } } ``` #### 3.3.2、測試程式碼 OneToOneTest.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/OneToOneTest.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import org.junit.Test; public class OneToOneTest { /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存學生基本資訊級聯儲存學生拓展資訊 */ @Test public void test1() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個學生基本資訊 StuBaseInfo stuBaseInfo1 = new StuBaseInfo(); stuBaseInfo1.setStuName("張三"); StuBaseInfo stuBaseInfo2 = new StuBaseInfo(); stuBaseInfo2.setStuName("李四"); // 建立兩個學生拓展資訊 StuOtherInfo stuOtherInfo1 = new StuOtherInfo(); stuOtherInfo1.setStuImg("http:img.caochenlei.com/001.png"); StuOtherInfo stuOtherInfo2 = new StuOtherInfo(); stuOtherInfo2.setStuImg("http:img.caochenlei.com/002.png"); stuBaseInfo1.setStuOtherInfo(stuOtherInfo1); stuBaseInfo2.setStuOtherInfo(stuOtherInfo2); stuOtherInfo1.setStuBaseInfo(stuBaseInfo1); stuOtherInfo2.setStuBaseInfo(stuBaseInfo2); entityManager.persist(stuBaseInfo1); entityManager.persist(stuBaseInfo2); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=create * 儲存學生拓展資訊級聯儲存學生基本資訊 */ @Test public void test2() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立兩個學生基本資訊 StuBaseInfo stuBaseInfo1 = new StuBaseInfo(); stuBaseInfo1.setStuName("張三"); StuBaseInfo stuBaseInfo2 = new StuBaseInfo(); stuBaseInfo2.setStuName("李四"); // 建立兩個學生拓展資訊 StuOtherInfo stuOtherInfo1 = new StuOtherInfo(); stuOtherInfo1.setStuImg("http:img.caochenlei.com/001.png"); StuOtherInfo stuOtherInfo2 = new StuOtherInfo(); stuOtherInfo2.setStuImg("http:img.caochenlei.com/002.png"); stuBaseInfo1.setStuOtherInfo(stuOtherInfo1); stuBaseInfo2.setStuOtherInfo(stuOtherInfo2); stuOtherInfo1.setStuBaseInfo(stuBaseInfo1); stuOtherInfo2.setStuBaseInfo(stuBaseInfo2); entityManager.persist(stuOtherInfo1); entityManager.persist(stuOtherInfo2); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢學生基本資訊級聯查詢學生拓展資訊 */ @Test public void test3() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuBaseInfo stuBaseInfo = entityManager.find(StuBaseInfo.class, 1L); System.out.println(stuBaseInfo); StuOtherInfo stuOtherInfo = stuBaseInfo.getStuOtherInfo(); System.out.println(stuOtherInfo); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 查詢學生拓展資訊級聯查詢學生基本資訊 */ @Test public void test4() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuOtherInfo stuOtherInfo = entityManager.find(StuOtherInfo.class, 1L); System.out.println(stuOtherInfo); StuBaseInfo stuBaseInfo = stuOtherInfo.getStuBaseInfo(); System.out.println(stuBaseInfo); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 更新學生基本資訊級聯更新學生拓展資訊 */ @Test public void test5() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuBaseInfo stuBaseInfo = entityManager.find(StuBaseInfo.class, 1L); stuBaseInfo.setStuSex("男"); StuOtherInfo stuOtherInfo = stuBaseInfo.getStuOtherInfo(); stuOtherInfo.setStuAddress("河北省"); entityManager.merge(stuBaseInfo); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 更新學生拓展資訊級聯更新學生基本資訊 */ @Test public void test6() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuOtherInfo stuOtherInfo = entityManager.find(StuOtherInfo.class, 2L); stuOtherInfo.setStuAddress("河南省"); StuBaseInfo stuBaseInfo = stuOtherInfo.getStuBaseInfo(); stuBaseInfo.setStuSex("女"); entityManager.merge(stuOtherInfo); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除學生基本資訊級聯刪除學生拓展資訊 */ @Test public void test7() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuBaseInfo stuBaseInfo = entityManager.find(StuBaseInfo.class, 1L); entityManager.remove(stuBaseInfo); transaction.commit(); entityManager.close(); } /** * 執行之前,修改hibernate.hbm2ddl.auto=update * 刪除學生拓展資訊級聯刪除學生基本資訊 */ @Test public void test8() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); StuOtherInfo stuOtherInfo = entityManager.find(StuOtherInfo.class, 2L); entityManager.remove(stuOtherInfo); transaction.commit(); entityManager.close(); } } ``` ## 第四章 Hibernate5 JPA的JPQL查詢 初始化資料,執行init方法: InitQueryData.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/InitQueryData.java) ```java package com.caochenlei.hibernate.jpa; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import org.junit.Test; public class InitQueryData { /** * 執行前:修改hibernate.hbm2ddl.auto=create * 執行此方法 * 執行後:修改hibernate.hbm2ddl.auto=update */ @Test public void init() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 建立一個客戶 Customer customer1 = new Customer(); customer1.setCustName("張三"); customer1.setCustSource("電視廣告"); // 建立十個聯絡人 for (int i = 1; i <= 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setLkmName("張三的聯絡人" + i); linkMan.setCustomer(customer1); customer1.getLinkMans().add(linkMan); entityManager.persist(linkMan); } entityManager.persist(customer1); // 建立一個客戶 Customer customer2 = new Customer(); customer2.setCustName("李四"); customer2.setCustSource("網路論壇"); // 建立十個聯絡人 for (int i = 1; i <= 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setLkmName("李四的聯絡人" + i); linkMan.setCustomer(customer2); customer2.getLinkMans().add(linkMan); entityManager.persist(linkMan); } entityManager.persist(customer2); // 建立一個客戶 Customer customer3 = new Customer(); customer3.setCustName("王五"); customer3.setCustSource("街邊告示"); // 建立十個聯絡人 for (int i = 1; i <= 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setLkmName("王五的聯絡人" + i); linkMan.setCustomer(customer3); customer3.getLinkMans().add(linkMan); entityManager.persist(linkMan); } entityManager.persist(customer3); // 建立一個客戶 Customer customer4 = new Customer(); customer4.setCustName("王五"); customer4.setCustSource("電視廣告"); entityManager.persist(customer4); transaction.commit(); entityManager.close(); } } ``` 以下的方法,均在下邊檔案進行測試: JPQLTest.java(全路徑:/hibernate_jpa/src/com/caochenlei/hibernate/jpa/JPQLTest.java) ### 4.1、簡單查詢 ```java @Test public void test1() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 查詢所有客戶 Query query = entityManager.createQuery("from Customer"); List list = query.getResultList(); for (Customer customer : list) { System.out.println(customer); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.2、別名查詢 ```java @Test public void test2() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 查詢所有客戶 Query query1 = entityManager.createQuery("from Customer c"); List list1 = query1.getResultList(); for (Customer customer : list1) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 查詢所有客戶 Query query2 = entityManager.createQuery("select c from Customer c"); List list2 = query2.getResultList(); for (Customer customer : list2) { System.out.println(customer); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.3、排序查詢 ```java @Test public void test3() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 採用鏈式呼叫,預設情況(升序) List list1 = entityManager.createQuery("from Customer order by cust_id").getResultList(); for (Customer customer : list1) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 採用鏈式呼叫,升序情況 List list2 = entityManager.createQuery("from Customer order by cust_id asc").getResultList(); for (Customer customer : list2) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 採用鏈式呼叫,降序情況 List list3 = entityManager.createQuery("from Customer order by cust_id desc").getResultList(); for (Customer customer : list3) { System.out.println(customer); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.4、條件查詢 ```java @Test public void test4() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 條件查詢:按引數位置繫結 Query query1 = entityManager.createQuery("from Customer where cust_source = ? and cust_name like ?"); query1.setParameter(1, "電視廣告"); query1.setParameter(2, "王%"); List list1 = query1.getResultList(); for (Customer customer : list1) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 條件查詢:按引數名稱繫結 Query query2 = entityManager.createQuery("from Customer where cust_source = :aaa and cust_name like :bbb"); query2.setParameter("aaa", "電視廣告"); query2.setParameter("bbb", "王%"); List list2 = query2.getResultList(); for (Customer customer : list2) { System.out.println(customer); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.5、投影查詢 ```java @Test public void test5() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 查詢所有客戶名稱:單個欄位查詢 Query query1 = entityManager.createQuery("select c.custName from Customer c"); List list1 = query1.getResultList(); for (Object cust_name : list1) { System.out.println(cust_name); } System.err.println("--------------------------------------------------"); // 查詢所有客戶名稱、客戶來源:多個欄位查詢,封裝到陣列中 Query query2 = entityManager.createQuery("select c.custName,c.custSource from Customer c"); List list2 = query2.getResultList(); for (Object[] objects : list2) { System.out.println(Arrays.toString(objects)); } System.err.println("--------------------------------------------------"); // 查詢所有客戶名稱、客戶來源:多個欄位查詢,封裝到物件中 // 請在Customer.java新增以下兩個構造方法,否則會執行失敗 // public Customer() // public Customer(String custName, String custSource) Query query3 = entityManager.createQuery("select new Customer(c.custName,c.custSource) from Customer c"); List list3 = query3.getResultList(); for (Customer customer : list3) { System.out.println(customer); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.6、分頁查詢 ```java @Test public void test6() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 分頁查詢 Query query = entityManager.createQuery("from LinkMan"); query.setFirstResult(0); query.setMaxResults(10); List list = query.getResultList(); for (LinkMan linkMan : list) { System.out.println(linkMan); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.7、分組查詢 ```java @Test public void test7() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 聚合函式:count(),max(),min(),avg(),sum() Object object = entityManager.createQuery("select count(*) from Customer").getSingleResult(); System.out.println(object); System.err.println("--------------------------------------------------"); // 分組統計: List list = entityManager.createQuery("select custSource,count(*) from Customer group by cust_source").getResultList(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(); } ``` ### 4.8、多表查詢 ```java @Test public void test8() { EntityManager entityManager = JPAUtil.getEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); // 內連線 List list1 = entityManager.createQuery("from Customer c inner join c.linkMans").getResultList(); for (Object[] objects : list1) { System.out.println(Arrays.toString(objects)); } System.err.println("--------------------------------------------------"); // 迫切內連線(hibernate獨有,將另一個物件的資料封裝到該物件中) List list2 = entityManager.createQuery("select distinct c from Customer c inner join fetch c.linkMans").getResultList(); for (Customer customer : list2) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 左外連線 List list3 = entityManager.createQuery("from Customer c left outer join c.linkMans").getResultList(); for (Object[] objects : list3) { System.out.println(Arrays.toString(objects)); } System.err.println("--------------------------------------------------"); // 迫切左外連線(hibernate獨有,將另一個物件的資料封裝到該物件中) List list4 = entityManager.createQuery("select distinct c from Customer c left outer join fetch c.linkMans").getResultList(); for (Customer customer : list4) { System.out.println(customer); } System.err.println("--------------------------------------------------"); // 右外連線 List list5 = entityManager.createQuery("from Customer c right outer join c.linkMans").getResultList(); for (Object[] objects : list5) { System.out.println(Arrays.toString(objects)); } System.err.println("--------------------------------------------------"); transaction.commit(); entityManager.close(