前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSH框架之Hibernate第四篇

SSH框架之Hibernate第四篇

作者头像
海仔
发布2019-09-18 14:42:28
3.5K0
发布2019-09-18 14:42:28
举报
文章被收录于专栏:海仔技术驿站海仔技术驿站

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://cloud.tencent.com/developer/article/1508654

代码语言:javascript
复制
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("98354834@qq.com");
					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 只做级联删除
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年09月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档