<!--
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!
-->
Hibernate chapter2 各表连接查询配置
最新推荐文章于 2024-07-02 00:50:11 发布