Hibernate chapter2 各表连接查询配置

 
<!--
	Hibernate chapter2 各表连接查询配置
	Goal:达到各种表之间的连接查询,也就是其中的关系的连接:多对单,单对单,单对多!
-->
简单说明:

	单对多/多对单:通俗点说就是多个对象与一个对象想对应,就拿学生表和班级表来说吧,
	一个班下面有很多学生,也就是说很多学生对应一个班级,这就是单对多/多对单的关系!
	
	单对单:也就是说一个对象只能对应一个对象!也就是说,比如现在多了一个表,这个表是
	记录有关班级的属性的,也就是数这个表中的一条(有且只有一条)数据只对应了一个班级!
	一个班级也只对应了那有且只有一条的数据的关系就叫单对单!
一,操作:
	
	a)数据库表格的建立:
	
	<!--			假设数据库中有这几张表:
	//班级表
	table ClassInfo(
		cid int primary key identity,
		cname varchar(20) not null,
		remark varchar(50) not null
	)
	
	//学生表
	table StuInfo(
		sid int primary key identity,
		sname varchar(20) not null,
		cid int foreign key (cid) references ClassInfo(cid),
		remark varchar(50)
	)
	
	//班级详情表(就是那个有且只有一条数据与班级表的单条数据相对应)
	table ClassDetail(
		cid int primary key,/*注意这里没有必要设置外键约束*/
		detail varchar(200),
		remark varchar(50)
	)
	-->
	
	b)实体的建立:

	//班级实体
	public class ClassInfo{
		private int cid;
		private String cname;
		private String remark;
		//注意这里了:为了能够查询到该班级下的所有学生,所以我们要设置一个学生的集合Set<StuInfo>
		//为什么是Set而不是List:List可以元素重复,Set不能有重复元素!
		private Set<StuInfo> stu_set;
		//省略了getter&setter
	}
	
	//学生实体
	public class StuInfo{
		private int sid;
		private String sname;
		private String remark;
		//为了能够查询到该学生所在的班级信息,所以这里不能建立外键,而是需要一个实体
		private ClassInfo classInfo;
		//省略了getter&setter
	}
	
	//班级详细信息实体
	public class ClassDetail{
		//为了能够达到单对单的关系,所以这个Id外键列需要写出来
		private int cid;
		private String detail;
		private String remark;
		//同理,也需要把班级实体引用过来!
		private ClassInfo classInfo;
		//省略getter&setter
	}
	
	c)关键的来了~配置xml文件!
	<!--记住加上这句来控制编码!
		<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
	-->
	
		1)班级->学生(单对多关系)
		
		//注:文件名:ClassInfo.hbm.xml
		<hibernate-mapping>
			<class name="com.shu.model.ClassInfo(类名)" table="ClassInfo(表名)">
				<id name="cid(字段ID列)" column="cid(表格ID列)">
					<generator class="native"/>
				</id>
				<property name="cname" column="cname"/>
				<property name="remark" column="remark"/>
				<!--开始配置一对多的关系-->
				<set name="stu_set(实体中的set名)">
					<key name="cid(依据那个列来进行的)"/>
					<one-to-many class="com.shu.model.StuInfo(many对象所在类)">
				</set>
			</class>
		</hibernate-mapping>
		
		<!--在java中进行查询,并且输入该班级的人数以及各个同学的信息
			//省略N创建各种对象的步骤
			ClassInfo ci=(ClassInfo)session.get(ClassInfo.class,班级ID);
			//得到属于该班级的人数:
			ci.getStu_set().size();
			//迭代输出信息
			Iterator<StuInfo> it=ci.getStu_set().iterator();
			while(it.hasNext()){
				StuInfo si=it.next();
				//do whatever you want!
			}
		-->
		
		2)学生->班级(多对单关系)
		
		//注:文件名:StuInfo.hbm.xml
		<hibernate-mapping>
			<class name="com.shu.model.StuInfo" table="StuInfo">
				<id name="sid" column="sid">
					<generator class="native">
				</id>
				<property name="sname" column="sname"/>
				<property name="remark" column="remark"/>
				<!--开始配置多对单关系-->
				<many-to-one class="com.shu.model.ClassInfo" name="classInfo(实体中的那个classInfo)" column="cid"/>
			</class>
		</hibernate-mapping>
		
		<!--在java中进行学员班级的连接查询
			//省略N创建各种对象的步骤
			StuInfo si=(StuInfo)session.get(StuInfo.class,学员id);
			ClassInfo ci=si.getClassInfo();
			//then do whatever you want!
		-->
		
		3)班级->班级详细信息(单对单关系)
		//注:文件名:ClassDetail.hbm.xml
		<hibernate-mapping>
			<class name="com.shu.model.ClassDetail" table="ClassTable">
				<id name="cid" column="cid">
					/*注意这里不一样了哦:用的是foreign,不是native了*/
					<generator class="foreign">
						/*还要记住配置里面的信息,中间的值就是在类中定义的那个引用类型的属性!*/
						<param name="property">classInfo</param>
					</generator>
				</id>
				<property name="detail" column="detail"/>
				<property name="remark" column="remark"/>
				<!--开始配置单对单关系-->
				<one-to-one name="classInfo" class="com.shu.model.ClassInfo"/>
			</class>
		</hibernate-mapping>
		
		<!--在java中的运用!
		//首先要了解单对单的作用:也就是我向ClassInfo插入数据时会自动想ClassDetail中插入数据
		//省略创建各个对象的步骤
		ClassInfo ci=new ClassInfo();
		ci.setCname("java_7");
		ci.setRemark("java7班");
		ClassDetail cd=new ClassDetail();
		cd.setClassInfo(ci);
		cd.setDetail("Sorry~No detail here!");
		cd.setRemark("the Java Seven");
		
		//关键的来了~session中只需要save(cd)就可以达到同时save(ci)的目的!
		session.save(cd);
		
		<!--
			//对了,这里突然想起一件事,也就是老师说的一个对象只对应一条数据!
			eg:
			ClassInfo ci=new ClassInfo();
			ci.setCname("java7");
			ci.setRemark("7");
			session.save(ci);
			ci.setCname("java8");
			ci.setRemark("8");
			session.save(ci);
			ci.setCname("java9");
			ci.setRemark("9");
			session.save(ci);
			这些代码运行下去其实数据中是不会存入三条数据的,就只会存入最后一条(已测试)!
		-->
		
二,关于表中的联级操作

	当配置信息中已形成各个表格中的关系时,这个的增删改就会产生联动关系,这个比较棘手~
	但是产生联动关系都是外键表影响主表(也就是ClassInfo影响StuInfo)!
	eg:
	1,当我们把ClassInfo中的cname改掉的话,就会对StuInfo产生比较头疼的影响!
	2,当我们删除外键表时要是有数据在主键表那么就会报错!
	
	为了解决以上问题,我们需要在标签<set>中添加两个属性
	万一没有set怎么办?呵呵~没有的话~就建一个吧~反正会用到的!
	<set name="" inverse="true" cascade="delete">
		<key>
		<one-to-many/>
	</set>
	
	inverse="true"表示修改外键表后依然要保持主键表中原有的数据!
	cascade="delete"表示可以进行联级删除,也就是时候可以通过外键表删除主键表!
	
三,把这个配置文件好好的记一下,我记忆力衰退了么~记着这么吃力!

<!--
Author:Lovingshu's Forever
Date:2011-11-08 21:23
Remark:Happy Birthday to Myself~and Call Of Duty:Modern Warfare 3!
-->
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值