SSH框架之Hibernate第四篇

  • 2019 年 10 月 5 日
  • 筆記

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/zhao1299002788/article/details/100623070

Hibernate中有兩套實現數據庫數據操作的方式 :  		hibernate前3天講解的都是 : hibernate自己的操作方式(純XML配置文件的方式)  		另一種方式是基於JPA的操作方式(通過註解的方式替代之前的部分XML)    	JPA相關概念:  		1.1JPA概述 : (java的持久化規範(規範即接口))  			全稱是 : Java Persistence API. 是SUN公司推出的一套基於ORM的規範.hibernate框架中提供了JPA的實現.  			JAP通過JDK5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中.  		1.2JPA要明確的  			a. JPA是一套ORM規範(算是一個接口),hibernate實現了JPA規範(算是一個實現類).  			b. hibernate中有自己的獨立ORM操作數據庫方式,也有JPA規範實現的操作數據庫方式.  			c. 在數據庫增刪改查操作中,我們hibernate和JPA的操作都要會.  		JPA和hibernate的關係?  			JPA是接口,hibernate是實現.  			所有的ORM框架都可以去實現JPA接口,通過JPA提供的一些接口來操作數據庫的數據.    		JPA的使用 :  			JPA是通過註解的方式來描述,對象和表的映射關係.  			之前的對象和表的映射關係配置是通過XML,今天要替換成註解的方式.    		注釋 : 給程序員看的.  		註解 : 給程序來使用的.  			為什麼要出現註解?  				一開始就是為了替代所有的XML配置文件.    				工作中兩種方式結合使用 :  					配置文件 + 註解  						如果是需要常常改動的程序 : 用配置文件.  						如果是定義好了不需要更改的程序 : 註解.    	2.1 2 JPA的環境搭建  		1 hibernate的環境(16個包)  		2 JPA的環境(1個包)    		2.2.2 創建配置文件  				要求:在src下面的META-INF文件夾下面創建一個名稱為persistence.xml的文件。  			配置文件的內容:  				<?xml version="1.0" encoding="UTF-8"?>  				<persistence xmlns="http://java.sun.com/xml/ns/persistence"  					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  					xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  					http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  					version="1.0">  					<!--Name屬性用於定義持久化單元的名字 (name必選,空值也合法);  						transaction-type 指定事務類型(可選)  							取值:  								JTA:默認值  								RESOURCE_LOCAL  					-->  					<persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL">    					  <properties>  							<!-- 生成DDL的策略 -->  							   <property name="hibernate.hbm2ddl.auto" value="update" />  							   <!-- 數據庫的連接信息 -->  							   <property name="hibernate.connection.driver_class"  										value="com.mysql.jdbc.Driver" />  							   <property name="hibernate.connection.url"  										value="jdbc:mysql://localhost:3306/hibernate_jpa"/>  							   <property name="hibernate.connection.username" value="root" />  							   <property name="hibernate.connection.password" value="1234" />  							   <!-- 指定方言 -->  							   <property name="hibernate.dialect"  										value="org.hibernate.dialect.MySQL5Dialect" />  							   <!-- 是否顯示SQL語句 -->  							   <property name="hibernate.show_sql" value="false" />  							   <!-- 是否格式化SQL語句 -->  							   <property name="hibernate.format_sql" value="true" />  						</properties>  					</persistence-unit>  				</persistence>    		2.2.3 編寫工具類,用於獲取JPA的操作數據庫對象  			public class HibernateUtils {  				//JPA的實體管理器工廠 : 相當於Hibernate的SessionFactory  				private static EntityManagerFactory em;  				//使用靜態代碼塊賦值  				static {  					//加載一次配置文件  					//注意 : 該方法參數必須和persistence.xml中persistence-unit標籤name屬性取值一致  					em = Persistence.createEntityManagerFactory("aaa");  				}  				/*  				 * 使用管理器工廠生產一個管理器對象  				 */  				//相當於獲取連接  				public static EntityManager getEntityManager() {  					return em.createEntityManager();  				}  			}    		jpa 的批量查詢方式 :  			類似咋們之前學習的query方式查詢 :  				1 : qr.getResultList() ;  類似之前的qr.list();  				2 : hibernate對於佔位符?    以前是從0開始,jpa是從1開始.  				3 : 聚合 qr.getSingleResult();   類似之前的uniqueResult();    		2.2.4 編寫實體類,並使用註解配置  			//級聯保存 (保存客戶的同時把關聯的聯繫人給保存了)  			//jpa的註解裏面 @OneToMany  添加屬性cascade = CascadeType.PERSIST_STORE  			//根據一的一方保存多的一方的數據.  			// 級聯保存 (保存聯繫人的同時把關聯的客戶給保存了)  			// jpa的註解裏面 @ManyToOne  添加屬性cascade=CascadeType.PERSIST  			//jpa的一對多沒有普通刪除  			// 級聯刪除  			// jpa的註解裏面 @OneToMany  添加屬性cascade=CascadeType.REMOVE (All)    			/**  			 * 客戶的實體類  			 */  			@Entity  			@Table(name="cst_customer")  			public class Customer implements Serializable {    				@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_address")  				private String custAddress;    				@Column(name="cust_phone")  				private String custPhone;    				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 getCustAddress() {  					return custAddress;  				}  				public void setCustAddress(String custAddress) {  					this.custAddress = custAddress;  				}  				public String getCustPhone() {  					return custPhone;  				}  				public void setCustPhone(String custPhone) {  					this.custPhone = custPhone;  				}  				@Override  				public String toString() {  					return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource  							+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress  							+ ", custPhone=" + custPhone + "]";  				}  			}    		2.3 常用註解說明  			@Entity  				作用 : 指定當前類是實體類.寫上此註解用於在創建SessionFactory/EntityManager時,加載映射配置.    			@Table  				作用 : 指定實體類和表之間的對應關係.  				屬性 :  					name : 指定數據庫表的名稱.    			@Id  				作用 : 指定當前字段是主鍵.    			@GeneratedValue  				作用 : 指定主鍵的生成方式.JPA的主鍵生成方式  				屬性 :  					strategy : 指定主鍵生成策略.JPA支持四種生成策略,    			@Column :  				作用 : 指定實體類屬性和數據庫表之間的對應關係.  				屬性 :  					name : 指定數據庫表的列名稱.  					unique : 是否唯一 .  					nullable : 是否可以為空  					inserttable : 是否可以插入  					updateable : 是否可以更新  					columnDefinition : 定義建表時創建此列的DDL.  					secondaryTable : 從表名.如果此列不建在主表上(默認鍵在主表),該屬性定義該列所在從表的名字.  			2.4主鍵生成策略  				通過annotation(註解)來映射hibernate實體的,基於annotation的hibernate主鍵標識為@Id,  				其生成規則由@GeneratedValue設定的.這裡的@id和@GeneratedValue都是JPA的標準用法。  				JPA提供的四種標準用法為TABLE,SEQUENCE,IDENTITY,AUTO。具體說明如下:  				2.4.1IDENTITY:主鍵由數據庫自動生成(主要是自動增長型)  				用法:  					@Id  					@GeneratedValue(strategy = GenerationType.IDENTITY)  					private Long custId;  				2.4.2SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。  				用法:  					@Id  					@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")  					@SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")  				說明:  					@SequenceGenerator源碼中的定義  					@Target({TYPE, METHOD, FIELD})  					@Retention(RUNTIME)  					public @interface SequenceGenerator {  						String name();  				 		String sequenceName() default "";  				 		int initialValue() default 0;  				 		int allocationSize() default 50;  					}  				name:表示該表主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的「generator」值中。  					sequenceName:屬性表示生成策略用到的數據庫序列名稱。  					initialValue:表示主鍵初識值,默認為0。  					allocationSize:表示每次主鍵值增加的大小,例如設置1,則表示每次插入新記錄後自動加1,默認為50。    				2.4.3AUTO:主鍵由程序控制。  				用法:  					@Id  					@GeneratedValue(strategy = GenerationType.AUTO)      				2.5JPA的CRUD操作  				2.5.1保存  				/**  					 * 保存一個實體  					 */  					@Test  					public void testAdd(){  						//定義對象  						Customer c = new Customer();  						c.setCustName("傳智學院");  						c.setCustLevel("VIP客戶");  						c.setCustSource("網絡");  						c.setCustIndustry("IT教育");  						c.setCustAddress("昌平區北七家鎮");  						c.setCustPhone("010-84389340");  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							em.persist(c);  							//提交事務  							tx.commit();  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}    				2.5.2修改  					/**  					 * 修改  					 */  					@Test  					public void testUpdate(){  						//定義對象  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							Customer c1 = em.find(Customer.class, 1L);  							c1.setCustName("江蘇傳智學院");  							//提交事務  							tx.commit();  //使用JPA中快照機制實現更新  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}    				merge方法實現修改  					@Test  					public void testMerge(){  						//定義對象  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							Customer c1 = em.find(Customer.class, 6L);  							c1.setCustName("江蘇傳智學院");  							em.clear();//把c1對象從緩存中清除出去  							em.merge(c1);  							//提交事務  							tx.commit();  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}  				2.5.3刪除  					/**  					 * 刪除  					 */  					@Test  					public void testRemove(){  						//定義對象  						EntityManager em=null;  							EntityTransaction tx=null;  							try{  								//獲取實體管理對象  								em=JPAUtil.getEntityManager();  								//獲取事務對象  								tx=em.getTransaction();  								//開啟事務  								tx.begin();  								//執行操作  								Customer c1 = em.find(Customer.class, 6L);  								em.remove(c1);  								//提交事務  								tx.commit();  							}catch(Exception e){  								//回滾事務  								tx.rollback();  								e.printStackTrace();  							}finally{  								//釋放資源  								em.close();  							}  					}  				2.5.4查詢一個  					/**  					 * 查詢一個:  					 * 	使用立即加載的策略  					 */  					@Test  					public void testGetOne(){  						//定義對象  						EntityManager em=null;  							EntityTransaction tx=null;  						 try{  								//獲取實體管理對象  								em=JPAUtil.getEntityManager();  								//獲取事務對象  								tx=em.getTransaction();  								//開啟事務  								tx.begin();  								//執行操作  								Customer c1 = em.find(Customer.class, 1L);  								//提交事務  								tx.commit();  								System.out.println(c1); //輸出查詢對象  						 }catch(Exception e){  								//回滾事務  								tx.rollback();  								e.printStackTrace();  							}finally{  								//釋放資源  								em.close();  							}  					}    				查詢實體的緩存問題  				@Test  					public void testGetOne(){  						//定義對象  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							Customer c1 = em.find(Customer.class, 1L);  							Customer c2 = em.find(Customer.class, 1L);  							System.out.println(c1 == c2);//輸出結果是true,EntityManager也有緩存  							//提交事務  							tx.commit();  							System.out.println(c1);  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}    				延遲加載策略的方法:  					/**  					 * 查詢一個:  					 * 	使用延遲加載策略  					 */  					@Test  					public void testLoadOne(){  						//定義對象  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							Customer c1 = em.getReference(Customer.class, 1L);  							//提交事務  							tx.commit();  							System.out.println(c1);  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}  				2.5.5查詢所有  					/**  					 * 查詢所有  					 * 	涉及的對象:  					 * 		Query(注意:不是Hibernate的Query)  					 *  	如何獲取:  					 *  		使用EntityManager的createQuery(String JPQL)方法;  					 *  	參數的含義  					 *  		JPQL:jpa  query language  					 *  		JPQL的寫法:  					 *  		表名使用實體類名稱替代  					 *  		列名使用實體類屬性名稱替代  					 *  		不能使用*號。查詢所有,需要在from關鍵字後面的類名上加別名  					 *  		例如: select c from Customer c  					 *  		查詢條件可以使用?作為參數佔位符。  					 *  		給佔位符賦值時,佔位符索引位置從1開始  					 *	獲取結果集的方法  					 *		getResultList():查詢結果是一個List集合  					 * 		getSingleResult():查詢結果是一個對象  					 */  					@Test  					public void testFindAll(){  						//定義對象  						EntityManager em=null;  						EntityTransaction tx=null;  						try{  							//獲取實體管理對象  							em=JPAUtil.getEntityManager();  							//獲取事務對象  							tx=em.getTransaction();  							//開啟事務  							tx.begin();  							//執行操作  							Query query = em.createQuery("select c from Customer c where custName like ? ");  							query.setParameter(1,"%學院%");  							List list = query.getResultList();  							//提交事務  							tx.commit();    							for(Object o : list){  								System.out.println(o);  							}  						}catch(Exception e){  							//回滾事務  							tx.rollback();  							e.printStackTrace();  						}finally{  							//釋放資源  							em.close();  						}  					}    		3.1一對多關係映射  			3.1.1常用註解  			3.1.1.1@OneToMany:  			作用:  				建立一對多的關係映射  			屬性:  				targetEntityClass:指定多的方的類的位元組碼  				mappedBy:指定從表實體類中引用主表對象的名稱。  				cascade:指定要使用的級聯操作  				fetch:指定是否採用延遲加載  				orphanRemoval:是否使用孤兒刪除  			3.1.1.2@ManyToOne  			作用:  				建立多對一的關係  			屬性:  				targetEntityClass:指定一的一方實體類位元組碼  				cascade:指定要使用的級聯操作  				fetch:指定是否採用延遲加載  				optional:關聯是否可選。如果設置為false,則必須始終存在非空關係。  			3.1.1.3@JoinColumn  			作用:  				用於定義主鍵字段和外鍵字段的對應關係。  			屬性:  				name:指定外鍵字段的名稱  				referencedColumnName:指定引用主表的主鍵字段名稱  				unique:是否唯一。默認值不唯一  				nullable:是否允許為空。默認值允許。  				insertable:是否允許插入。默認值允許。  				updatable:是否允許更新。默認值允許。  				columnDefinition:列的定義信息。  			3.1.2配置代碼  			3.1.2.1客戶配置  			/**  			 * 客戶的實體類  			 * 明確使用的註解都是JPA規範的  			 * 所以導包都要導入javax.persistence包下的  			 *  			 */  			@Entity//表示當前類是一個實體類  			@Table(name="cst_customer")//建立當前實體類和表之間的對應關係  			public class Customer implements Serializable {    				@Id//表明當前私有屬性是主鍵  				@GeneratedValue(strategy=GenerationType.IDENTITY)//指定主鍵的生成策略  				@Column(name="cust_id")//指定和數據庫表中的cust_id列對應  				private Long custId;  				@Column(name="cust_name")//指定和數據庫表中的cust_name列對應  				private String custName;  				@Column(name="cust_source")//指定和數據庫表中的cust_source列對應  				private String custSource;  				@Column(name="cust_industry")//指定和數據庫表中的cust_industry列對應  				private String custIndustry;  				@Column(name="cust_level")//指定和數據庫表中的cust_level列對應  				private String custLevel;  				@Column(name="cust_address")//指定和數據庫表中的cust_address列對應  				private String custAddress;  				@Column(name="cust_phone")//指定和數據庫表中的cust_phone列對應  				private String custPhone;    				@OneToMany(targetEntity=LinkMan.class,mappedBy="customer")  				private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);    				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 getCustAddress() {  					return custAddress;  				}  				public void setCustAddress(String custAddress) {  					this.custAddress = custAddress;  				}  				public String getCustPhone() {  					return custPhone;  				}  				public void setCustPhone(String custPhone) {  					this.custPhone = custPhone;  				}  				public Set<LinkMan> getLinkmans() {  					return linkmans;  				}  				public void setLinkmans(Set<LinkMan> linkmans) {  					this.linkmans = linkmans;  				}  				@Override  				public String toString() {  					return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource  							+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress  							+ ", custPhone=" + custPhone + "]";  				}  			}  			3.1.2.2聯繫人配置  			/**  			 * 聯繫人的實體類(數據模型)  			*/  			@Entity  			@Table(name="cst_linkman")  			public class LinkMan implements Serializable {  				@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_position")  				private String lkmPosition;  				@Column(name="lkm_memo")  				private String lkmMemo;    				//多對一關係映射:多個聯繫人對應客戶  				@ManyToOne(targetEntity=Customer.class)  				@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")  				private Customer customer;//用它的主鍵,對應聯繫人表中的外鍵    				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 getLkmPosition() {  					return lkmPosition;  				}  				public void setLkmPosition(String lkmPosition) {  					this.lkmPosition = lkmPosition;  				}  				public String getLkmMemo() {  					return lkmMemo;  				}  				public void setLkmMemo(String lkmMemo) {  					this.lkmMemo = lkmMemo;  				}  				public Customer getCustomer() {  					return customer;  				}  				public void setCustomer(Customer customer) {  					this.customer = customer;  				}  				@Override  				public String toString() {  					return "LinkMan [lkmId=" + lkmId + ", lkmName=" + lkmName + ", lkmGender=" + lkmGender + ", lkmPhone="  							+ lkmPhone + ", lkmMobile=" + lkmMobile + ", lkmEmail=" + lkmEmail + ", lkmPosition=" + lkmPosition  							+ ", lkmMemo=" + lkmMemo + "]";  				}  			}  			3.2多對多關係映射  			3.2.1常用註解:  			3.2.1.1@ManyToMany  			作用:  				用於映射多對多關係  			屬性:  				cascade:配置級聯操作。  				fetch:配置是否採用延遲加載。  				targetEntity:配置目標的實體類。映射多對多的時候不用寫。  			3.2.1.2@JoinTable  			作用:  				針對中間表的配置  			屬性:  				name:配置中間表的名稱  				joinColumns:中間表的外鍵字段關聯當前實體類所對應表的主鍵字段  				inverseJoinColumn:中間表的外鍵字段關聯對方表的主鍵字段    			3.2.1.3@JoinColumn  			作用:  				用於定義主鍵字段和外鍵字段的對應關係。  			屬性:  				name:指定外鍵字段的名稱  				referencedColumnName:指定引用主表的主鍵字段名稱  				unique:是否唯一。默認值不唯一  				nullable:是否允許為空。默認值允許。  				insertable:是否允許插入。默認值允許。  				updatable:是否允許更新。默認值允許。  				columnDefinition:列的定義信息。    			3.2.2配置代碼  			3.2.2.1用戶配置  			/**  			 * 用戶的數據模型  			*/  			@Entity  			@Table(name="sys_user")  			public class SysUser implements Serializable {    				@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;    				//多對多關係映射  				@ManyToMany(mappedBy="users")  				private Set<SysRole> roles = new HashSet<SysRole>(0);    				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;  				}  				public Set<SysRole> getRoles() {  					return roles;  				}  				public void setRoles(Set<SysRole> roles) {  					this.roles = roles;  				}  				@Override  				public String toString() {  					return "SysUser [userId=" + userId + ", userCode=" + userCode + ", userName=" + userName + ", userPassword="  							+ userPassword + ", userState=" + userState + "]";  				}  			}      			3.2.2.2角色配置  			/**  			 * 角色的數據模型  			*/  			@Entity  			@Table(name="sys_role")  			public class SysRole implements Serializable {    				@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;    				//多對多關係映射  				@ManyToMany  				@JoinTable(name="user_role_rel",//中間表的名稱  						  //中間表user_role_rel字段關聯sys_role表的主鍵字段role_id  				joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},  						  //中間表user_role_rel的字段關聯sys_user表的主鍵user_id  				inverseJoinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")}  				)  				private Set<SysUser> users = new HashSet<SysUser>(0);      				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;  				}  				public Set<SysUser> getUsers() {  					return users;  				}  				public void setUsers(Set<SysUser> users) {  					this.users = users;  				}  				@Override  				public String toString() {  					return "SysRole [roleId=" + roleId + ", roleName=" + roleName + ", roleMemo=" + roleMemo + "]";  				}      			}      			第4章JPA的多表操作  			4.1一對多關係的增刪改操作  			4.1.1保存操作  			保存原則:先保存主表,再保存從表。  				/**  				 * 保存操作  				 * 需求:  				 * 	保存一個客戶和一個聯繫人  				 * 要求:  				 * 	創建一個客戶對象和一個聯繫人對象  				 *  建立客戶和聯繫人之間關聯關係(雙向一對多的關聯關係)  				 *  先保存客戶,再保存聯繫人  				 */  				@Test  				public void test1(){  					//創建客戶和聯繫人對象  					Customer c = new Customer();//瞬時態  					c.setCustName("TBD雲集中心");  					c.setCustLevel("VIP客戶");  					c.setCustSource("網絡");  					c.setCustIndustry("商業辦公");  					c.setCustAddress("昌平區北七家鎮");  					c.setCustPhone("010-84389340");    					LinkMan l = new LinkMan();//瞬時態  					l.setLkmName("TBD聯繫人");  					l.setLkmGender("male");  					l.setLkmMobile("13811111111");  					l.setLkmPhone("010-34785348");  					l.setLkmEmail("[email protected]");  					l.setLkmPosition("老師");  					l.setLkmMemo("還行吧");    					//建立他們的雙向一對多關聯關係  					l.setCustomer(c);  					c.getLinkmans().add(l);  					//獲取JPA操作對照  					EntityManager em = JPAUtil.getEntityManager();  					//獲取JPA事務對象  					EntityTransaction tx= em.getTransaction();  						//開啟事務  						tx.begin();  					//按照要求:先保存客戶,再保存聯繫人(此時符合保存原則:先保存主表,再保存從表)  					em.persist(c);  					em.persist(l);  					tx.commit();  				}    			JPA註解的配置方式:不涉及多一條update語句的問題  			4.1.2刪除操作  				/**  				 * 刪除操作  				 * 	刪除從表數據:可以隨時任意刪除。  				 * 	刪除主表數據:  				 * 		有從表數據引用  				 * 			1、不能刪除  				 * 			2、如果還想刪除,使用級聯刪除  				 * 		沒有從表數據引用:隨便刪  				 *  				 * 在實際開發中,級聯刪除請慎用!(在一對多的情況下)  				 */  				@Test  				public void test3(){  					//獲取JPA操作對照  					EntityManager em = JPAUtil.getEntityManager();  					//獲取JPA事務對象  					EntityTransaction tx= em.getTransaction();  						//開啟事務  						tx.begin();  					//查詢id為1的客戶  					Customer c1 = em.find(Customer.class, 2L);  					//刪除id為1的客戶  					em.remove(c1);  					tx.commit();  				}    			級聯刪除的配置:  			@OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.ALL) //用CascadeType.REMOVE也可以  			private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);  			4.2多對多關係的增刪操作  			4.2.1保存操作  				/**  				 * 需求:  				 * 	保存用戶和角色  				 * 要求:  				 * 	創建2個用戶和3個角色  				 * 	讓1號用戶具有1號和2號角色(雙向的)  				 * 	讓2號用戶具有2號和3號角色(雙向的)  				 *  保存用戶和角色  				 */  				@Test  				public void test1(){  					//創建對象  					SysUser u1 = new SysUser();  					u1.setUserName("用戶1");  					SysUser u2 = new SysUser();  					u2.setUserName("用戶2");    					SysRole r1 = new SysRole();  					r1.setRoleName("角色1");  					SysRole r2 = new SysRole();  					r2.setRoleName("角色2");  					SysRole r3 = new SysRole();  					r3.setRoleName("角色3");    					//建立關聯關係  					u1.getRoles().add(r1);  					u1.getRoles().add(r2);  					r1.getUsers().add(u1);  					r2.getUsers().add(u1);    					u2.getRoles().add(r2);  					u2.getRoles().add(r3);  					r2.getUsers().add(u2);  					r3.getUsers().add(u2);    					//獲取JPA操作對照  					EntityManager em = JPAUtil.getEntityManager();  					//獲取JPA事務對象  					EntityTransaction tx= em.getTransaction();  						//開啟事務  						tx.begin();  					em.persist(u1);  					em.persist(u2);  					em.persist(r1);  					em.persist(r2);  					em.persist(r3);  					tx.commit();  				}    			JPA註解的配置方式:不涉及保存失敗的問題:  			4.2.2刪除操作  				/**  				 * 刪除操作  				 * 	在多對多的刪除時,雙向級聯刪除根本不能配置  				 * 禁用  				 *	如果配了的話,如果數據之間有相互引用關係,可能會清空所有數據  				 */  				@Test  				public void test2(){  					//獲取JPA操作對照  					EntityManager em = JPAUtil.getEntityManager();  					//獲取JPA事務對象  					EntityTransaction tx= em.getTransaction();  						//開啟事務  						tx.begin();  					SysUser u1 = em.find(SysUser.class,3L);  					em.remove(u1);  					tx.commit();  				}    			在多對多映射配置中不能出現雙向級聯刪除的配置,無論註解還是XML配置    		5.2JPA和hibernate中操作數據的方法對照  			操作	Hibernate中的方法	JPA中的方法	說明  			保存操作	save(Object entity)	persist(Object entity)	共同點:都是把臨時態對象轉成了持久態。  			區別:  			提供者不一樣:  				save方法是hibernate提供的。  				persist方法是JPA規範提供的。  			在沒有事務的情況下:  				save會去數據庫中保存,hibernate提供了一個內置的事務來執行。  				persist什麼都不會做。  			更新操作	update (Object entity)	merge (Object entity)	Hibernate和jpa都可以利用快照機制,不調用任何方法去更新。  			Update方法在更新時,如果遇到一級緩存已經包含了一個相同OID的對象會報錯。merge則可以執行成功。  			刪除操作	delete (Object entity)	remove (Object entity)	都是刪除一個實體  			查詢一個操作	get (Class clazz,Serializable id)  			load(Class clazz,Serializable id)	find(Class clazz,Object id)  			getReerence(Class clazz,Object id)	get和find都是立即加載。load和getReference一樣都是延遲加載。  			查詢所有操作	Query:使用HQL語句查詢	Query:使用JPQL查詢	查詢語句的形式不一樣。  			查詢返回唯一結果操作	uniqueResult()	getSingleResult()	查詢都是返回一個唯一的結果。    		JPA一對多的註解配置:  			案例:  				// ps: jpa提供的註解都在:javax.persistence包下  				@Entity  				@Table(name="cst_customer")  				public  class Customer  				{  					@Id  					@Column(name="cust_id")  					@GeneratedValue(strategy=GenerationType.IDENTITY)  					private Long cust_id; // '客戶編號(主鍵)',    					@Column(name="cust_name")  					private String cust_name; // '客戶名稱(公司名稱)',    					@Column(name="cust_source")  					private String cust_source; // '客戶信息來源',    					@Column(name="cust_industry")  					private String cust_industry; // '客戶所屬行業',    					@Column(name="cust_level")  					private String cust_level; // '客戶級別',    					@Column(name="cust_address")  					private String cust_address; // '客戶聯繫地址',    					@Column(name="cust_phone")  					private String cust_phone; // '客戶聯繫電話    					// 有多的一方的集合  					/*targetEntity:對方的類型  					 * mappedBy:自己在對方里的屬性名稱   (mappedBy寫在哪方,哪方意味着放棄外鍵的維護)  					 *  					 * */  					@OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.REMOVE)  					private Set<LinkMan> linkmans=new HashSet();    					@Entity  					@Table(name="cst_linkman")  					public class LinkMan  					{  						@Id  						@Column(name="lkm_id")  						@GeneratedValue(strategy=GenerationType.IDENTITY)  						private Long lkm_id;// '聯繫人編號(主鍵)',    						@Column(name="lkm_name")  						private String lkm_name;// '聯繫人姓名',    						@Column(name="lkm_gender")  						private String lkm_gender;// '聯繫人性別',    						@Column(name="lkm_phone")  						private String lkm_phone;// '聯繫人辦公電話',    						@Column(name="lkm_mobile")  						private String lkm_mobile;// '聯繫人手機',    						@Column(name="lkm_email")  						private String lkm_email;// '聯繫人郵箱',    						@Column(name="lkm_qq")  						private String lkm_qq;// '聯繫人qq',    						@Column(name="lkm_position")  						private String lkm_position;// '聯繫人職位',    						@Column(name="lkm_memo")  						private String lkm_memo;// '聯繫人備註',    						// 有一的一方的對象 PERSIST  						@ManyToOne(targetEntity=Customer.class,cascade=CascadeType.PERSIST)  						/*name:代表着外鍵字段的名稱*/  						/*referencedColumnName:指向的主鍵字段的命名稱*/  						@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")  						private Customer customer;    			多表對多表的註解配置:  					@Entity  					@Table(name="sys_user")  					public class User  					{  						@Id  						@Column(name="user_id")  						@GeneratedValue(strategy=GenerationType.IDENTITY)  						private Long user_id;// '用戶id',  						@Column(name="user_code")  						private String user_code;// '用戶賬號',  						@Column(name="user_name")  						private String user_name;// '用戶名稱',  						@Column(name="user_password")  						private String user_password;// '用戶密碼',  						@Column(name="user_state")  						private String user_state;// '1:正常,0:暫停',    						// 有角色的集合  						/*targetEntity:對方的類型  						 *  						 *  						 * */  						@ManyToMany(targetEntity=Role.class,cascade=CascadeType.ALL)  						/*name: 中間表的名稱  						joinColumns:自己在中間表的一些配置  						inverseJoinColumns:對方在中間表的一些配置*/  						@JoinTable(name="sys_user_role",  						joinColumns={  									/*name:自己在中間表的外鍵字段名稱  									referencedColumnName:指向自己的主鍵字段名*/  							@JoinColumn(name="user_id",referencedColumnName="user_id")  						},  						inverseJoinColumns={  									/*name:對方在中間表的外鍵字段名稱  									referencedColumnName:指向的對方的主鍵字段名稱*/  								@JoinColumn(name="role_id",referencedColumnName="role_id")  						})  						private Set<Role> roles=new HashSet();    					@Entity  					@Table(name="sys_role")  					public class Role  					{  						@Id  						@Column(name="role_id")  						@GeneratedValue(strategy=GenerationType.IDENTITY)  						private Long role_id;// 主鍵id    						@Column(name="role_name")  						private String role_name;// '角色名稱',  						@Column(name="role_memo")  						private String role_memo;// '備註',    						// 有用戶的集合  						/*targetEntity:對方的類型  						 * mappedBy:自己在對方的屬性名  						 * */  						@ManyToMany(targetEntity=User.class,mappedBy="roles")  						private Set<User> users=new HashSet();    			JPA需要在項目src下新建一個META-INF文件夾在文件夾裏面配置以下信息:  				例如 :  					<?xml version="1.0" encoding="UTF-8"?>  					<persistence xmlns="http://java.sun.com/xml/ns/persistence"  						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  						xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  					http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"  						version="2.0">  							<!-- ps:當前根目錄下必須得有一個持久化單元(至少要有一個數據庫的連接信息配置) -->  							<persistence-unit name="aaa">  										<!-- 數據庫的連接信息 -->  										<properties>  												<!-- 必選5項 -->  											<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>  											<property name="hibernate.connection.url" value="jdbc:mysql:///hibernate3"></property>  											<property name="hibernate.connection.username" value="root"></property>  											<property name="hibernate.connection.password" value="1234"></property>  											<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property>    												<!-- 可選的 -->  											<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"></property>  											<property name="hibernate.show_sql" value="true"></property>  											<property name="hibernate.format_sql" value="true"></property>  											<property name="hibernate.hbm2ddl.auto" value="update"></property>    										</properties>  							</persistence-unit>  					</persistence>  		JPA單表操作 :  			例如 :  				package cn.baidu.demo;    				public class Demo1  				{  					@Test //需求:保存一個客戶  					public void t1()  					{  						// 加載配置文件--返回一個類似Sessionfactory的對象  						EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");  						// 類似session  						EntityManager em = factory.createEntityManager();  						// 獲取事務  						EntityTransaction tx = em.getTransaction(); // 事務未開啟  						// 開啟事務  						tx.begin();    						// 保存操作  						Customer ct = new Customer();  						ct.setCust_name("李冰冰");  						em.persist(ct); // 類似save()      						// 手動提交  						tx.commit();    						// 釋放資源  						em.close();    					}    					@Test //查詢1  					public void t2()  					{  						EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");  						EntityManager em = factory.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 查詢  						Customer ct = em.find(Customer.class, 1L); // 立即加載  類似get()  						System.out.println(ct);  						tx.commit();  						em.close();  					}    					@Test //查詢2  					public void t3()  					{  						EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");  						EntityManager em = factory.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 查詢2  						Customer ct = em.getReference(Customer.class, 1L); //延遲加載  類似load()  						System.out.println(ct);  						tx.commit();  						em.close();  					}      					@Test //修改  					public void t4()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 修改  						Customer ct = em.find(Customer.class, 1L);  						ct.setCust_name("rose");  						em.merge(ct);  //類似update    						tx.commit();  						em.close();  					}    					@Test //修改 jpa支持一級緩存?  支持  					public void t5()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 修改  						Customer ct = em.find(Customer.class, 1L);  						ct.setCust_name("rose123");      						tx.commit();  						em.close();  					}      					@Test //刪除  					public void t6()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						//刪除  						Customer ct = em.find(Customer.class, 1L);  						em.remove(ct);  // 類似之前的delete()      						tx.commit();  						em.close();  					}      					/// jpa的批量查詢方式  							// 類似咱們之前學習的query方式  							// 1 qr.getResultList();        //類似之前的 qr.list()  							// 2 hibernate對於佔位符?是從0開始  jpa是從1開始  							// 3  聚合    qr.getSingleResult();  //類似之前的  qr.uniqueResult();    					@Test  					public void t7()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 全查  						Query qr = em.createQuery("from Customer");  						List<Customer> list = qr.getResultList();  //類似之前的 qr.list()  						for (Customer customer : list) {  							System.out.println(customer);  						}    						tx.commit();  						em.close();  					}      					@Test  					public void t8()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 條件  						Query qr = em.createQuery("from Customer where cust_name like ?");  						qr.setParameter(1, "b%"); // 注意:hibernate對於佔位符?是從0開始  jpa是從1開始    						List<Customer> list = qr.getResultList();  						for (Customer customer : list) {  							System.out.println(customer);  						}  						tx.commit();  						em.close();  					}      					@Test  					public void t9()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 分頁  						Query qr = em.createQuery("from Customer");  						qr.setFirstResult(1);  						qr.setMaxResults(3);    						List<Customer> list = qr.getResultList();  						for (Customer customer : list) {  							System.out.println(customer);  						}  						tx.commit();  						em.close();  					}      					@Test  					public void t10()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 單列  						Query qr = em.createQuery("select cust_name from Customer");  						List<Object> list = qr.getResultList();  						for (Object object : list) {  							System.out.println(object);  						}  						tx.commit();  						em.close();  					}    					@Test  					public void t11()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 多列  						Query qr = em.createQuery("select cust_id,cust_name from Customer");  						List<Object[]> list = qr.getResultList();  						for (Object[] object : list) {  							System.out.println(Arrays.toString(object));  						}  						tx.commit();  						em.close();  					}    					@Test  					public void t12()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 投影  						Query qr = em.createQuery("select new Customer(cust_id,cust_name) from Customer");  						List<Customer> list = qr.getResultList();  						for (Customer customer : list) {  							System.out.println(customer);  						}  						tx.commit();  						em.close();  					}      					@Test  					public void t13()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 排序  						Query qr = em.createQuery("from Customer order by cust_id desc");  						List<Customer> list = qr.getResultList();  						for (Customer customer : list) {  							System.out.println(customer);  						}  						tx.commit();  						em.close();  					}    					@Test  					public void t14()  					{  						EntityManager em = JPAutils.createEntityManager();  						EntityTransaction tx = em.getTransaction();  						tx.begin();    						// 聚合  						Query qr = em.createQuery("select avg(cust_id) from Customer");  						Object obj = qr.getSingleResult();  						System.out.println(obj);  						tx.commit();  						em.close();  					}  				}    		JPA一對多表的操作 :  			/*  		一對多的操作*/  		public class Demo2  		{  			@Test  // 保存一的客戶3個聯繫人  			public void t1()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();  				Customer ct = new Customer();  				ct.setCust_name("馬總");  				LinkMan l1 = new LinkMan();  				l1.setLkm_name("大秘");  				LinkMan l2 = new LinkMan();  				l2.setLkm_name("中秘");  				LinkMan l3 = new LinkMan();  				l3.setLkm_name("小秘");    				// 雙向關聯  				ct.getLinkmans().add(l1);  				ct.getLinkmans().add(l2);  				ct.getLinkmans().add(l3);  				l1.setCustomer(ct);  				l2.setCustomer(ct);  				l3.setCustomer(ct);    				//保存  				em.persist(ct);  				em.persist(l1);  				em.persist(l2);  				em.persist(l3);  				tx.commit();  				em.close();  			}      			@Test  // 級聯保存 (保存客戶的同時把關聯的聯繫人給保存了)  						// jpa的註解裏面  @OneToMany  添加屬性cascade=CascadeType.PERSIST  			public void t2()  // 根據一的一方保存多的一方的數據(掌握)  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();  				Customer ct = new Customer();  				ct.setCust_name("馬總");  				LinkMan l1 = new LinkMan();  				l1.setLkm_name("大秘");  				LinkMan l2 = new LinkMan();  				l2.setLkm_name("中秘");  				LinkMan l3 = new LinkMan();  				l3.setLkm_name("小秘");    				// 雙向關聯  				ct.getLinkmans().add(l1);  				ct.getLinkmans().add(l2);  				ct.getLinkmans().add(l3);  				l1.setCustomer(ct);  				l2.setCustomer(ct);  				l3.setCustomer(ct);    				//保存  				em.persist(ct);  				/*em.persist(l1);  				em.persist(l2);  				em.persist(l3);*/  				tx.commit();  				em.close();  			}      			@Test  // 級聯保存 (保存聯繫人的同時把關聯的客戶給保存了)  			// jpa的註解裏面 @ManyToOne  添加屬性cascade=CascadeType.PERSIST  			public void t3() // 根據多的一方保存一的一方的數據(不常用)  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();  				Customer ct = new Customer();  				ct.setCust_name("馬總");  				LinkMan l1 = new LinkMan();  				l1.setLkm_name("大秘");  				LinkMan l2 = new LinkMan();  				l2.setLkm_name("中秘");  				LinkMan l3 = new LinkMan();  				l3.setLkm_name("小秘");    				// 雙向關聯  				ct.getLinkmans().add(l1);  				ct.getLinkmans().add(l2);  				ct.getLinkmans().add(l3);  				l1.setCustomer(ct);  				l2.setCustomer(ct);  				l3.setCustomer(ct);    				//保存  				/*em.persist(ct);*/  				em.persist(l1);  				em.persist(l2);  				em.persist(l3);  				tx.commit();  				em.close();  			}      			@Test  // 普通刪除  			public void  t4()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();    				Customer ct = em.find(Customer.class, 4L);  				em.remove(ct);  				tx.commit();  				em.close();  			}      			@Test  // 級聯刪除  			// jpa的註解裏面 @OneToMany  添加屬性cascade=CascadeType.REMOVE (All)  			public void  t5()  //根據一的一方刪除關聯的多的一方的所有數據(掌握)  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();    				Customer ct = em.find(Customer.class, 4L);  				em.remove(ct);  				tx.commit();  				em.close();  			}    		}    		JPA多表對多表的操作 :  			package cn.baidu.demo;    		import javax.persistence.CascadeType;  		import javax.persistence.EntityManager;  		import javax.persistence.EntityTransaction;  		import javax.persistence.ManyToMany;    		import org.junit.Test;    		import cn.baidu.domain.Role;  		import cn.baidu.domain.User;  		import cn.baidu.utils.JPAutils;    		/*  		多對多的操作*/  		public class Demo3  		{  			@Test  //普通保存  保存2個用戶 3個角色  			public void t1()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();    				User user1 = new User();  				user1.setUser_name("jack");  				User user2 = new User();  				user2.setUser_name("rose");    				Role r1 = new Role();  				r1.setRole_name("員工");  				Role r2 = new Role();  				r2.setRole_name("班主任");  				Role r3 = new Role();  				r3.setRole_name("助教");    				// 雙向關聯  				user1.getRoles().add(r1);  				user1.getRoles().add(r3);  				user2.getRoles().add(r1);  				user2.getRoles().add(r2);    				r1.getUsers().add(user1);  				r1.getUsers().add(user2);  				r2.getUsers().add(user2);  				r3.getUsers().add(user1);    				// 保存  				em.persist(user1);  				em.persist(user2);  				em.persist(r1);  				em.persist(r2);  				em.persist(r3);    				tx.commit();  				em.close();  			}    			// jpa多對多的級聯操作  				// 級聯保存: 保存用戶的同時把關聯的角色給保存了(不用)  					// @ManyToMany 添加cascade=cascade=CascadeType.PERSIST  			@Test  			public  void t2()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();  				User user1 = new User();  				user1.setUser_name("jack");  				User user2 = new User();  				user2.setUser_name("rose");    				Role r1 = new Role();  				r1.setRole_name("員工");  				Role r2 = new Role();  				r2.setRole_name("班主任");  				Role r3 = new Role();  				r3.setRole_name("助教");    				// 雙向關聯  				user1.getRoles().add(r1);  				user1.getRoles().add(r3);  				user2.getRoles().add(r1);  				user2.getRoles().add(r2);    				r1.getUsers().add(user1);  				r1.getUsers().add(user2);  				r2.getUsers().add(user2);  				r3.getUsers().add(user1);    				// 保存  				em.persist(user1);  				em.persist(user2);  				/*em.persist(r1);  				em.persist(r2);  				em.persist(r3);*/    				tx.commit();  				em.close();  			}    			@Test  // 普通刪除(常用)  			public void t3()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();    				User user = em.find(User.class, 1L);  				em.remove(user);  				tx.commit();  				em.close();  			}    			@Test  // 級聯刪除(避免去使用)  			public void t4()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();    				User user = em.find(User.class, 2L);  				em.remove(user);  				tx.commit();  				em.close();  			}      			// jpa的用戶角色分配  					// 添加角色  					// 刪除角色  					// 修改角色  			@Test  			public void t5()  			{  				EntityManager em = JPAutils.createEntityManager();  				EntityTransaction tx = em.getTransaction();  				tx.begin();  				// 獲取用戶  				User user = em.find(User.class, 3L);  				// 獲取班主任  				Role rl = em.find(Role.class, 6L);  				//給用戶添加  				user.getRoles().add(rl);  				tx.commit();  				em.close();  			}      		}    		總結:  	JPA的作用?  		給所有的orm框架提供了一套接口  	好處: 所有的ORM框架只要實現了這個JPA接口,用來操作數據庫數據的方式和方法以及註解都一致了      	jpa的環境搭建: 在hibernate的環境基礎上多加一個包--hibernate-entitymanager-5.0.7.Final.jar      	單表的映射  		@Entity  實體類  		@Table(name="cst_customer")  與表的映射  		@Id   指定OID屬性  		@Column(name="cust_id") 指定映射的字段  		@GeneratedValue(strategy=GenerationType.IDENTITY)  指定主鍵的生成策略    	crud:  		persist()  			----保存    		find()  : 立即加載  		getReference():延遲加載  			-----單條數據的oid查詢    		merge()  			---修改      		remove()  			---刪除      	批量查詢:  		  類似之前的query方式      	一對多:  		一: @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")  		多: @ManyToOne(targetEntity=LinkMan.class)  			一對多的關係配置:  				@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")      	多對多:  		多(被動): @ManyToMany(targetEntity=User.class,mappedBy="roles")  		多(主動): @ManyToMany(targetEntity=Role.class)  			 多對多的關係配置:  				@JoinTable(name="中間表的名稱",joinColumns="自己在中間表的配置(數組)"  				inverseJoinColumns="對方在中間表的配置(數組)")      	級聯:  		cascade=CascadeType.ALL  做級聯保存以及級聯刪除  		cascade=CascadeType.PERSIST 只做級聯保存  		cascade=CascadeType.REMOVE 只做級聯刪除