六、映射 -- 总结(关联映射、组件映射、继承映射)

一、关联映射

				
	+++ 关联映射
			
			  1.一对多、多对一映射
					 
					 案例: 部门与员工
				     表结构:
				     	    两张表。(主表、外键表)
						    部门表的主键约束员工表的外键字段			
					 映射:
						    配置主表与外键表的映射文件
						 
					
				b.多对多映射
					
					 案例: 开发者与项目组
				     表结构:
						   三张表(两张主表、关联关系表)
						   (开发者表、项目表、开发者与项目的关联关系表)					
					 映射:
						   配置开发者表映射、项目表映射
					
						  		
			   c.一对一映射
					
					 案例: 用户与身份证信息
				     
				     表结构:
						   两张表(主表、外键表)
						   一条用户信息对应一条身份证信息  【一对一】
					 
					 映射:
							配置两个映射文件。
					
					 分类:		
					 	  一对一映射有两种方式:
											1.基于外键的映射
											  主键表约束外键表,外键是普通字段
											  
											2.基于主键的映射
											  主键表约束外键表,外键是外键表的主键	   
								
								
			   e.组件映射、继承映射			

	一对多:
		<set name="映射的集合属性" table="(可选)集合属性对应的外键表">
		   <key column="外键表的,外键字段" />
		   <one-to-many class="集合元素的类型" />
		</set>
	
	多对一:
	    <many-to-one name="对象属性" class="对象类型" column="外键字段字段" />
	
	多对多
	    <set name="" table="">
	        <key column="" />
	        <many-to-many column="" class="">
	    </set>
1.1 一对多、多对一映射
	实体:
			
			public class DeptEntity {			
				private int deptId;
				private String deptName;
				private String deptCode;				
				//一对多映射
				private Set<EmpEntity>  empSet;
			}

			public class EmpEntity {
				private int id;
				private String name;
				private String desc;
				//多对一
				private DeptEntity dept;			
			}

	 映射:
	 		Dept.hbm.xml(主表,一对多)
						key关键字: 映射的是外键表的外键字段
						one-to-many: 映射外键表。class指定外键表对应的java类型。由于package指定了包,所以可以简写类名。否则,写完整类名
						<!-- set 映射外键表 -->	
					 	<set name="empSet" >
							<key column="t_deptId1"></key>
							<one-to-many class="EmpEntity"></one-to-many>
						</set>
		
			
			Emp.hbm.xml(外键表,多对一)
					name="dept" 映射的部门属性
					  
			<!-- 	
				多对一映射配置
				Employee 映射关键点:
				1.  映射的部门属性  :  dept
				2.  映射的部门属性,对应的外键字段: dept_id
				3.  部门的类型
			 -->
			 <many-to-one name="dept"  column="t_deptId1" class="DeptEntity"></many-to-one>

		 	
2.1.1 数据库表结构
>>>>>> 部门表

在这里插入图片描述
在这里插入图片描述

>>>>>> 员工表

在这里插入图片描述
在这里插入图片描述

2.1.2 示例
>>>>>> Dept.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.d_one2Many" >
	
	<class name="DeptEntity" table="t_dept">
		
		<id name="deptId" column="t_id" >
			<generator class="native"></generator>
		</id>	
	
		<!-- 非主键,映射 -->		
		<property name="deptName" column="t_name"></property>
		<property name="deptCode" column="t_code"></property>
		
		
		<!-- 
			一对多关联映射配置  (通过部门管理到员工)
			Dept 映射关键点:
			1.  指定 映射的集合属性: "emps"
			2.  集合属性对应的集合表: "t_employee"
			3.  集合表的外键字段   "t_employee. dept_id"
			4.  集合元素的类型
			
			inverse=false  set集合映射的默认值; 表示有控制权
			
					<set name="empSet" table="t_emp">
			
		 -->
		<set name="empSet" >
			<key column="t_deptId1"></key>
			
			<!-- 映射外键表。class指定外键表对应的java类型。由于package指定了包,所以可以简写类名。否则,写完整类名 -->
			<one-to-many class="EmpEntity"></one-to-many>
		</set>
	</class>

</hibernate-mapping>
>>>>>> DeptEntity .java
	public class DeptEntity {
		
		private int deptId;
		private String deptName;
		private String deptCode;
		
		//一对多映射
		private Set<EmpEntity>  empSet;
	}	
>>>>>> EmpEntity.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.d_one2Many" >
	
	<class name="EmpEntity" table="t_emp">
		
		<id name="id" column="t_empId" >
			<generator class="native"></generator>
		</id>	
	
		<!-- 非主键,映射 -->		
		<property name="name" column="t_empName"></property>
		<property name="desc" column="t_desc"></property>
		
			
		<!-- 
			多对一映射配置
			Employee 映射关键点:
			1.  映射的部门属性  :  dept
			2.  映射的部门属性,对应的外键字段: dept_id
			3.  部门的类型
		 -->
		 <many-to-one name="dept"  column="t_deptId1" class="DeptEntity"></many-to-one>

	
	</class>

</hibernate-mapping>
>>>>>> EmpEntity.java
	public class EmpEntity {
		
		private int id;
		private String name;
		private String desc;
		
		//多对一
		private DeptEntity dept;
	}	
>>>>>> App.java
public class App3 {
	
	private static Session session;
	static {
		session= new Configuration().configure()
				.addClass(EmpEntity.class)
				.addClass(DeptEntity.class)
				.buildSessionFactory()
				.openSession();
	}
	
	public static void main(String[] args) {
		
		
		
		save2();
	}
	
	/**
	 * 	从部门的角度维度数据【从一的方向维护关系】
	 */
	private static void save1() {
		Set<EmpEntity>  empSet=new HashSet<EmpEntity>();
		
		EmpEntity  emp=new EmpEntity();
		emp.setName("xxx1");
		emp.setDesc("1");
		empSet.add(emp);		
		EmpEntity  emp2=new EmpEntity();
		emp2.setName("xxx2");
		emp2.setDesc("2");
		empSet.add(emp2);
		
		
		//从一的方向保存数据
		DeptEntity  dept=new DeptEntity();	
		dept.setDeptCode("001");
		dept.setDeptName("develop");
		dept.setEmpSet(empSet);
		
		Transaction tr = session.beginTransaction();
		
		session.save(emp);
		session.save(emp2);
		session.save(dept);
		tr.commit();
	}
	
	
	/**
	 * 	从员工的角度维度数据【从多的方向维护关系,推荐】
	 */
	private static void save2() {
		
		DeptEntity  dept=new DeptEntity();	
		dept.setDeptCode("001");
		dept.setDeptName("develop");
		
		EmpEntity  emp=new EmpEntity();
		emp.setName("xxx1");
		emp.setDesc("1");
		emp.setDept(dept);

		EmpEntity  emp2=new EmpEntity();
		emp2.setName("xxx2");
		emp2.setDesc("2");
		emp2.setDept(dept);

		
		Transaction tr = session.beginTransaction();
		
		session.save(dept);
		
		session.save(emp);
		session.save(emp2);
		
		tr.commit();
	}
}

2.1.3 关键字
		案例:部门与员工
		
		inverse关键字设置到set节点上,作用是设置控制权:
				<set name="empSet" inverse="true" >
							<key column="t_deptId1"></key>					
							<!-- 映射外键表。class指定外键表对应的java类型。由于package指定了包,所以可以简写类名。否则,写完整类名 -->
							<one-to-many class="EmpEntity"></one-to-many>
				</set>
				
				1.inverse=false,有控制权。
							可以从配置的一方维护关联关系。
										保存数据
										清除关联关系
										删除数据
				2.inverse=true,无控制权。
							 不可以从配置的一方维护关联关系。
							 			不能保存数据
							 			不能清除关联关系
							 			不能删除数据			
							 							
		
		 cascade关键字可以设置到set节点、many-to-one节点上,设置级联操作:
				
				设置到set节点上:
					<set name="empSet" cascade="delete"  >
							<key column="t_deptId1"></key>
							
							<!-- 映射外键表。class指定外键表对应的java类型。由于package指定了包,所以可以简写类名。否则,写完整类名 -->
							<one-to-many class="EmpEntity"></one-to-many>
					</set>
					
				设置到many-to-one节点上:	
					 <many-to-one name="dept" column="t_deptId1" class="DeptEntity" cascade="delete" ></many-to-one>


1.2 多对多映射
	实体:
				public class DeveloperEnTity {			
					private int id;
					private String name;
					private int age;				
					//多对多
					private Set<ProjectEntity>  projectSet;
				}

				public class ProjectEntity {				
					private int pId;
					private String pName;
					private String pDesc;				
					//多对多映射
					private Set<DeveloperEnTity>  developerSet;	
				}
				

	 映射:
	 		多对多映射,双方的映射配置都是映射的第三张关联表
	 		DeveloperEnTity.hbm.xml(主表)
						key关键字: 映射的是外键表的外键字段
						many-to-many: 映射外键表的第二个外键字段。(column指定第二个外键字段的名称。class指定第二个外键字段的来演)
						<set name="projectSet" table="t_pro_dev"  >
							<key column="t_developerId"></key>			
							<many-to-many column="t_projectId" class="ProjectEntity"></many-to-many>
						</set>
	
		
			
			ProjectEntity.hbm.xml(主表)
						key关键字: 映射的是外键表的外键字段
						many-to-many: 映射外键表的第二个外键字段。(column指定第二个外键字段的名称。class指定第二个外键字段的来演)
						<set name="developerSet" table="t_pro_dev" >
							<key column="t_projectId"></key>			
							<many-to-many column="t_developerId" class="DeveloperEnTity"></many-to-many>
						</set>
	

		 	
1.2.1 数据库表结构
>>>>>> 开发者表

在这里插入图片描述
在这里插入图片描述

>>>>>> 项目表

在这里插入图片描述
在这里插入图片描述

>>>>>> 关联表

在这里插入图片描述
在这里插入图片描述

2.1.2 示例
>>>>>> DeveloperEnTity.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.e_many2Many" >
	
	<class name="DeveloperEnTity" table="t_developer">
		
		<id name="id" column="t_id" >
			<generator class="native"></generator>
		</id>	
	
		<!-- 非主键,映射 -->		
		<property name="name" column="t_name"></property>
		<property name="age" column="t_age"></property>
	
		<set name="projectSet" table="t_pro_dev"  >
			<key column="t_developerId"></key>			
			<many-to-many column="t_projectId" class="ProjectEntity"></many-to-many>
		</set>
	
	</class>

</hibernate-mapping>
>>>>>> DeveloperEnTity .java
	public class DeveloperEnTity {
			
			private int id;
			private String name;
			private int age;
			
			//多对多
			private Set<ProjectEntity>  projectSet=new HashSet<ProjectEntity>();
		}	
>>>>>> ProjectEntity.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.e_many2Many" >
	
	<class name="ProjectEntity" table="t_project" >
		
		<id name="pId" column="t_id" >
			<generator class="native"></generator>
		</id>	
	
		<!-- 非主键,映射 -->		
		<property name="pName" column="t_name"></property>
		<property name="pDesc" column="t_desc"></property>
	
		<set name="developerSet" table="t_pro_dev" >
			<key column="t_projectId"></key>			
			<many-to-many column="t_developerId" class="DeveloperEnTity"></many-to-many>
		</set>
	
	</class>

</hibernate-mapping>
>>>>>> ProjectEntity .java

	public class ProjectEntity {		
		private int pId;
		private String pName;
		private String pDesc;
		
		//多对多映射
		private Set<DeveloperEnTity>  developerSet=new HashSet<DeveloperEnTity>();
	}	
>>>>>> App.java
public class App {
	
	private static Session session;
	
	static {
		  session= new Configuration().configure()
				.addClass(DeveloperEnTity.class)
				.addClass(ProjectEntity.class)
				.buildSessionFactory()
				.openSession();
	}
	
	/**
	 * list查询
	 * @param args
	 */
	public static void main(String[] args) {
		
		save();
	}
	
	
	public void testGet() {
		
	}

	
	/**
	 * 	多对多保存数据【只能通过一方维护另一方,不能重复维护,否则报错。】
	 * @param args
	 */
	private static void save() {
		//开发者1
		DeveloperEnTity   developer=new DeveloperEnTity();
		developer.setName("小白");
		//开发者2
		DeveloperEnTity   developer2=new DeveloperEnTity();
		developer2.setName("小白2");
		
		//项目
		ProjectEntity pro=new ProjectEntity();
		pro.setpName("MRP");
		
		//维护关系
		pro.getDeveloperSet().add(developer);
		pro.getDeveloperSet().add(developer2);

		//保存数据
		session.beginTransaction();
		
		session.save(developer);
		session.save(developer2);
		session.save(pro);
		
		session.getTransaction().commit();
	}
	
	/**
	 * 	多对多保存数据【在项目一方设置级联操作】
	 * @param args
	 */
	private static void save2() {
		//开发者1
		DeveloperEnTity   developer=new DeveloperEnTity();
		developer.setName("小白");
		//开发者2
		DeveloperEnTity   developer2=new DeveloperEnTity();
		developer2.setName("小白2");
		
		//项目
		ProjectEntity pro=new ProjectEntity();
		pro.setpName("MRP");
		
		//维护关系
		pro.getDeveloperSet().add(developer);
		pro.getDeveloperSet().add(developer2);

		//保存数据
		session.beginTransaction();
		
//		session.save(developer);
//		session.save(developer2);
		
		session.save(pro);//必须设置级联操作
		
		session.getTransaction().commit();
	}
}

1.3 一对一映射
1.3.1 主键表映射外键表的外键字段,外键字段为普通字段
	
	实体:
			
			public class User {					
					private String  userId;
					private String name;
					private int age;
					private Card card;
			}

			public class Card {
				
				private String cardNum;
				private String place;
				private User  user;			
			}
			

	 映射:
	 		User.hbm.xml(主表)
						<one-to-one name="card" class="Card"></one-to-one>	

			
			Card.hbm.xml(外键表)
						many-to-one: 将一个实体映射为一个外键字段
						unique="true" 给外键字段添加唯一约束
						<many-to-one name="user" unique="true" column="userId"  class="User"></many-to-one>			


		 	
1.3.1.1 数据库表结构
>>>>>> 用户表

在这里插入图片描述
在这里插入图片描述

>>>>>> 身份证表

在这里插入图片描述
在这里插入图片描述

1.3.1.2 示例
>>>>>> User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.i_one2one"  >
	
	<class name="User" table="h_user" >
		
		<id name="userId" column="userId">
			<generator class="uuid"/>
		</id>
			
		<property name="name" column="name"></property>	
		<property name="age" column="age"></property>	
		
		<!-- 一对一映射:没有外键方 -->
		<one-to-one name="card" class="Card"></one-to-one>	
			
	</class>

</hibernate-mapping>
>>>>>> User .java
	public class User {
		
		private String  userId;
		private String name;
		private int age;
		private Card card;
	}	
>>>>>> Card.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.i_one2one"  >
	
	<class name="Card" table="h_card" >
		
		<id name="cardNum" column="cardNum">
			<generator class="assigned"></generator>
		</id>
				
	
		<!-- 非主键,映射 -->	
		<property name="place" column="place"></property>	
		
		<!-- 一对一映射:有外键方 
				many-to-one: 将一个实体映射为一个外键字段
				unique="true" 给外键字段添加唯一约束
				
		-->
		<many-to-one name="user" unique="true" column="userId"  class="User"></many-to-one>			
	</class>

</hibernate-mapping>
>>>>>> Card.java
	public class Card {
		
		private String cardNum;
		private String place;
		private User  user;
	}	
>>>>>> App.java
public class App {
	private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Card.class).addClass(User.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();

		//用户
		User p=new User();
		p.setName("小白");
		p.setAge(12);
		
		//身份证
		Card c=new Card();
		c.setCardNum("320321199401027233");
		c.setPlace("xxx");
		
		//关系
		c.setUser(p);
		
		//保存
		session.save(p);
		session.save(c);
		tr.commit();
		
		
		
	}
}


1.3.2 主键表映射外键表的外键字段,外键字段为主键字段
	
	实体:
			
			public class User {					
					private String  userId;
					private String name;
					private int age;
					private Card card;
			}

			public class Card {
				
				private String cardNum;
				private String place;
				private User  user;			
			}
			

	 映射:
	 		User.hbm.xml(主表)
						<!-- 一对一映射:没有外键方 -->
						<one-to-one name="card" class="Card"></one-to-one>	

			
			Card.hbm.xml(外键表)
						many-to-one: 将一个实体映射为一个外键字段
						unique="true" 给外键字段添加唯一约束
						<!-- 
								一对一映射:有外键方(基于主键的映射)
								constrained="true" 指定在主键上添加外键约束
						 -->
						<one-to-one name="user" constrained="true" class="User"></one-to-one>	
		


		 	
1.3.2.1 数据库表结构
>>>>>> 用户表

在这里插入图片描述
在这里插入图片描述

>>>>>> 身份证表

在这里插入图片描述
在这里插入图片描述

1.3.2.2 示例
>>>>>> User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.i_one2one"  >
	
	<class name="User" table="h_user" >
		
		<id name="userId" column="userId">
			<generator class="uuid"/>
		</id>
			
		<property name="name" column="name"></property>	
		<property name="age" column="age"></property>	
		
		<!-- 一对一映射:没有外键方 -->
		<one-to-one name="card" class="Card"></one-to-one>	
			
	</class>

</hibernate-mapping>
>>>>>> User .java
	public class User {
		
		private String  userId;
		private String name;
		private int age;
		private Card card;
	}	
>>>>>> Card.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.i_one2one_2"  >
	
	<class name="Card" table="h_card" >
		
		<!-- 
			id节点指定的是主键映射,则userId是主键
			主键生成方式:foreign,即把别的表的主键作为当前表的主键。
					  			property 指定引用的对象,  引用对象 --》对象全名 --》对象的映射 --》table(id)
					  						根据引用的对象,找到对象的全名  org.jsoft.i_one2one_2.user
					  						根据引用的对象全名,找到引用对象的映射
					  						根据引用的对象映射,找到引用表的ID。
					  						把别的表的主键作为当前表的主键
		 -->
		<id name="userId" column="user_id">
			<generator class="foreign">
				<param name="property">user</param>
			</generator>
		</id>
				
	
		<!-- 非主键,映射 -->	
		<property name="place" column="place"></property>	
		<property name="cardNum" column="cardNum"></property>	
		
		
		<!-- 
			一对一映射:有外键方(基于主键的映射)
					constrained="true" 指定在主键上添加外键约束
		 -->
		<one-to-one name="user" constrained="true" class="User"></one-to-one>	
		
	</class>

</hibernate-mapping>
>>>>>> Card.java
	public class Card {
		
		private String cardNum;
		private String place;
		private User  user;
	}	
>>>>>> App.java
public class App {
	private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Card.class).addClass(User.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();

		//用户
		User p=new User();
		p.setName("小白");
		p.setAge(12);
		
		//身份证
		Card c=new Card();
		c.setCardNum("320321199401027233");
		c.setPlace("xxx");
		
		//关系
		c.setUser(p);
		
		//保存
		session.save(p);
		session.save(c);
		tr.commit();
		
		
		
	}
}


二、组件映射

		+++ 组合关系
				一个类中包含了另外一个类。这2个类中就是组合关系。
				需求: 汽车与车轮
2.1 数据库表结构

在这里插入图片描述
在这里插入图片描述

2.2 示例
Car.java

public class Car {
	private String id;
	private String name;
	private Whele  whele;
}

Whele .java

public class Whele {	
	private int count;
	private int size;
	private String color;
}

Car.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.j_component"  >
	
	<class name="Car" table="t_car" >
		<id name="id" column="id">
			<generator class="uuid"></generator>
		</id>
				
	
		<!-- 非主键,映射 -->	
		<property name="name" column="name"></property>	
		
		<!-- 组件映射 -->
		<component name="whele" class="Whele">
				<property name="count" column="count"></property>	
				<property name="size" column="size"></property>	
				<property name="color" column="color"></property>			
		</component>
	</class>

</hibernate-mapping>
App.java
public class App {
private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Car.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();
		
		//车轮
		Whele whele=new Whele();
		whele.setColor("Yellow");
		whele.setCount(4);
		whele.setSize(14);
		
		//车
		Car c=new Car();
		c.setName("大众");
		c.setWhele(whele);
		
		//保存
		session.save(c);
		
		tr.commit();
		
		
		
	}
}

三、继承映射

	
	+++ 继承关系
			一个类继承另外一个类。这2个类中就是继承关系。


	+++ 继承映射:
			1.简单继承映射
					有多少个子类就有多少个映射文件
					
			2.复杂继承映射
			
3.1 简单继承映射
		实体:
				public class Animal {	
					private int id;
					private String name;
					private String color;
				}	
				
				public class Cat  extends Animal{
					//吃老鼠
					private boolean eatMouse;
				}
		
		映射文件:
				Cat.hbm.xml:
								<class name="Cat" table="t_cat" >
										<id name="id" column="id">
											<generator class="native"></generator>
										</id>									
										<property name="name" column="name"></property>	
										<property name="color" column="color"></property>											
										<property name="eatMouse" column="eatMouse"  ></property>											
									</class>
3.1.1 数据库表结构

在这里插入图片描述
在这里插入图片描述

3.1.2 示例
>>>>>> Cat.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.k_entends1"  >
	
	<class name="Cat" table="t_cat" >
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
				
	
		<!-- 非主键,映射 -->	
		<property name="name" column="name"></property>	
		<property name="color" column="color"></property>	
		
		<property name="eatMouse" column="eatMouse"  ></property>	
		
	</class>

</hibernate-mapping>
>>>>>> Animal .java
		public class Animal {
			
			private int id;
			private String name;
			private String color;
		}	
>>>>>> Cat.java
		public class Cat  extends Animal{
				//吃老鼠
				private boolean eatMouse;
		}	
>>>>>> App.java
public class App {
private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Cat.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		
		save();
	}

	private static void query() {
		Query qr = session.createQuery("from Cat");
		List<Cat> list = qr.list();
		System.out.println(list);
	}
	
	/**
	 * 保存
	 */
	private static void save() {
		Transaction tr = session.beginTransaction();
		
		Cat c=new Cat();
		c.setColor("Yello");
		c.setName("小白");
		c.setEatMouse(true);
		
		//保存
		session.save(c);
		
		tr.commit();
	}
}

3.2 复杂继承映射
3.2.1 所有子类都映射都父类映射的表中(一张表,一个映射文件)
	 
	 应用场景:
			  子类教多,且子类较为简单,即只有个别属性!
			  好处:因为使用一个映射文件, 减少了映射文件的个数。
			  缺点:
			  		1.不符合数据库设计原则.
			  		2.一个映射文件: Animal.hbm.xml (如何区分是哪个子类的信息?)


	
	实体:
			public class Animal {
				private int id;
				private String name;
				private String color;
			}

			public class Cat  extends Animal{
				//吃老鼠
				private String eatMouse;
			}

			public class Monkey  extends Animal{
				private String eatBranana;
			}
	
	映射文件:Animal.hbm.xml

						<?xml version="1.0"?>
						<!DOCTYPE hibernate-mapping PUBLIC 
							"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
							"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">						
						<hibernate-mapping package="org.jsoft.k_entends2"  >							
							<class name="Animal" table="t_animal" >
								<id name="id" column="id">
									<generator class="native"></generator>
								</id>									
								<!-- 指定鉴别器字段  	column可写可不写,column默认为class	-->
								<discriminator 	column="type"></discriminator>									
								<!-- 非主键,映射 -->	
								<property name="name" column="name"></property>	
								<property name="color" column="color"></property>	
														
								<!-- 子类:
										 每个子类都用subclass节点映射
										 注意:一定要指定鉴别器字段,否则报错。
										             鉴别器字段的作用是在数据库中区别每一个记录的类型
								     
								     discriminator-value="cat1" 
								     		指定鉴别器字段的值。即鉴别器字段type的值。
								     		如果不指定,默认为该子类的全路径
								 -->
								<subclass name="Cat" discriminator-value="cat1">
										<property name="eatMouse" column="eatMouse"  ></property>	
								</subclass>
								
								<!-- 映射子类 -->
								<subclass name="Monkey"  >
										<property name="eatBranana" column="eatBranana"  ></property>	
								</subclass>
								
							</class>
						
						</hibernate-mapping>	
	

3.2.1.1 数据库表结构

在这里插入图片描述
在这里插入图片描述

3.2.1.2 示例
>>>>>>Animal.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.k_entends2"  >
	
	<class name="Animal" table="t_animal" >
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
			
		<!-- 指定鉴别器字段  	column可写可不写,column默认为class	-->
		<discriminator 	column="type"></discriminator>		
	
		<!-- 非主键,映射 -->	
		<property name="name" column="name"></property>	
		<property name="color" column="color"></property>	
		
		
	
		<!-- 子类:
				 每个子类都用subclass节点映射
				 注意:一定要指定鉴别器字段,否则报错。
				             鉴别器字段的作用是在数据库中区别每一个记录的类型
		     
		     discriminator-value="cat1" 
		     		指定鉴别器字段的值。即鉴别器字段type的值。
		     		如果不指定,默认为该子类的全路径
		 -->
		<subclass name="Cat" discriminator-value="cat1">
				<property name="eatMouse" column="eatMouse"  ></property>	
		</subclass>
		
		<!-- 映射子类 -->
		<subclass name="Monkey"  >
				<property name="eatBranana" column="eatBranana"  ></property>	
		</subclass>
		
	</class>

</hibernate-mapping>
>>>>>>Animal.java
		public class Animal {	
			private int id;
			private String name;
			private String color;
	 }
>>>>>>Cat .java
	public class Cat  extends Animal{
	
	//吃老鼠
	private String eatMouse;
	}
>>>>>>Monkey.java
		public class Monkey  extends Animal{
			
			private String eatBranana;
		}	
>>>>>>App.java
public class App {
private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Animal.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();
		
		//猫
		Cat c=new Cat();
		c.setColor("Yello");
		c.setName("小白");
		c.setEatMouse("1");
		
		//猴子
		Monkey m=new Monkey();
		m.setColor("Blue");
		m.setName("小黑");

		//保存
		session.save(c);
		session.save(m);

		tr.commit();
	}

}

3.2.2 每个类各自映射一张表,父类也对应表(N个类N个表)
    一个映射文件,存储所有的子类; 子类父类都对应表;
        缺点:表结构比较复杂,插入一条子类信息,需要用2条sql:
              即往父类插入、往子类插入!
	
	实体:
			public class Animal {
				private int id;
				private String name;
				private String color;
			}

			public class Cat  extends Animal{
				//吃老鼠
				private String eatMouse;
			}

			public class Monkey  extends Animal{
				private String eatBranana;
			}
	
	映射文件Animal.hbm.xml:
							<?xml version="1.0"?>
							<!DOCTYPE hibernate-mapping PUBLIC 
								"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
								"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
							
							<hibernate-mapping package="org.jsoft.k_entends3"  >
								
								<class name="Animal" table="t_animal" >
									<id name="id" column="id">
										<generator class="native"></generator>
									</id>
									
									<!-- 非主键,映射 -->	
									<property name="name" column="name"></property>	
									<property name="color" column="color"></property>	
									
									<!--  -->
									<joined-subclass name="Cat" table="t_cat">
										<key column="t_cat_id"></key>
										<property name="eatMouse" column="eatMouse"></property>	
									</joined-subclass>	
									
									<joined-subclass name="Monkey" table="t_monkey">
										<key column="t_monkey_id"></key>
										<property name="eatBranana" column="eatBranana"></property>	
									</joined-subclass>
								
								</class>
							
							</hibernate-mapping>
3.2.2.1 数据库表结构
>>>>>> Animal 父类动物表

在这里插入图片描述
在这里插入图片描述

>>>>>> Cat子类表

在这里插入图片描述
在这里插入图片描述

>>>>>> Monkey子类表

在这里插入图片描述
在这里插入图片描述

3.2.2.2 示例
>>>>>>Animal.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.k_entends3"  >
	
	<class name="Animal" table="t_animal" >
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		
		<!-- 非主键,映射 -->	
		<property name="name" column="name"></property>	
		<property name="color" column="color"></property>	
		
		<!--  -->
		<joined-subclass name="Cat" table="t_cat">
			<key column="t_cat_id"></key>
			<property name="eatMouse" column="eatMouse"></property>	
		</joined-subclass>	
		
		<joined-subclass name="Monkey" table="t_monkey">
			<key column="t_monkey_id"></key>
			<property name="eatBranana" column="eatBranana"></property>	
		</joined-subclass>
	
	</class>

</hibernate-mapping>
>>>>>>Animal.java
		public class Animal {	
			private int id;
			private String name;
			private String color;
	 }
>>>>>>Cat .java
	public class Cat  extends Animal{
	
	//吃老鼠
	private String eatMouse;
	}
>>>>>>Monkey.java
		public class Monkey  extends Animal{
			
			private String eatBranana;
		}	
>>>>>>App.java

public class App {
private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Animal.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();
		
		//猫
		Cat c=new Cat();
		c.setColor("Yello");
		c.setName("小白");
		c.setEatMouse("1");
		
		//猴子
		Monkey m=new Monkey();
		m.setColor("Blue");
		m.setName("小黑");

		//保存
		session.save(c);
		session.save(m);

		tr.commit();
	}

}

3.2.3 每个类各自映射一张表,父类不对应表(N-1表)
3.2.3.1 数据库表结构
>>>>>> Cat子类表

在这里插入图片描述
在这里插入图片描述

>>>>>> Monkey子类表

在这里插入图片描述
在这里插入图片描述

3.2.2.2 示例
>>>>>>Animal.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="org.jsoft.k_entends4"  >
	
	<!-- 
		abstract="true"
				指定实体类对象不对应表,即在数据库端不生成表。
				如果不写这个,则会生成Animal表,但是表为空。
	 -->
	<class name="Animal" abstract="true" >
		
		<!-- 如果用union-subclass 节点,主键生成策略不能为自增长,必须手动指定-->
		<id name="id" column="id">
			<generator class="uuid"></generator>
		</id>
		
		<!-- 非主键,映射 -->	
		<property name="name" column="name"></property>	
		<property name="color" column="color"></property>	
		
		<!--  -->
		<union-subclass name="Cat" table="t_cat">
			<property name="eatMouse" column="eatMouse"></property>	
		</union-subclass>	
		
		<union-subclass name="Monkey" table="t_monkey">
			<property name="eatBranana" column="eatBranana"></property>	
		</union-subclass>
	
	</class>

</hibernate-mapping>
>>>>>>Animal.java
		public class Animal {	
			private int id;
			private String name;
			private String color;
	 }
>>>>>>Cat .java
	public class Cat  extends Animal{
	
	//吃老鼠
	private String eatMouse;
	}
>>>>>>Monkey.java
		public class Monkey  extends Animal{
			
			private String eatBranana;
		}	
>>>>>>App.java
public class App {
private static Session session;
	
	static {
		SessionFactory sf=new Configuration().configure().addClass(Animal.class).buildSessionFactory();
		session = sf.openSession();
	}
	
	public static void main(String[] args) {
		Transaction tr = session.beginTransaction();
		
		//猫
		Cat c=new Cat();
		c.setColor("Yello");
		c.setName("小白");
		c.setEatMouse("1");
		
		//猴子
		Monkey m=new Monkey();
		m.setColor("Blue");
		m.setName("小黑");

		//保存
		session.save(c);
		session.save(m);

		tr.commit();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值