您的位置:首页 > 其它

关于hibernate的onetomany和manytomany

2009-11-20 19:15 393 查看
1.one to many

(1)对于1这一方的操作与多的一方级联级
增加1时 可以普通的双增,也就是先new一的一方,在new多的一方的多个,把一的外键给多的几个实体,分别save一和多
要点 new了几个实体就要save几次
例如:
Dept dept=new Dept();
dept.setD_name("就业");

Ren ren=new Ren();
ren.setR_name("小明");
Ren ren1=new Ren();
ren1.setR_name("小王");

ren.setDept(dept);
ren1.setDept(dept);

session.save(dept);
session.save(ren);
session.save(ren1);

增加1时 可以级联增加
要点 把多的一方new出来后,放到一的一方的set里,最后只save一的一方,并且只保存一次
例如:
Dept dept=new Dept();
dept.setD_name("就业2");

Ren ren=new Ren();
ren.setR_name("小明1");
Ren ren1=new Ren();
ren1.setR_name("小王1");

dept.getRenSet().add(ren);
dept.getRenSet().add(ren1);
session.save(dept);

--------------------------------增加修改和删除时与cascade=all有关:如果没有级联 只有为null一种情况!------------------------

删除一的时候 如果new 从表与之关联外键变null
例如:
Dept dept=new Dept();
dept.setD_id("4028803b223f64ad01223f64e4f00001");
session.delete(dept);

删除一的时候 先查出来load 全删除(主从)
例如:
session.delete(session.load(Dept.class, "4028803b223f629a01223f62d1520001"));

修改一的时候 如果new 从表与之关联外键变null
例如:
Dept dept=new Dept();
dept.setD_id("4028803b223f64ad01223f64e4f00001");
dept.setD_name("就业5");
session.update(dept);

修改一的时候 先查出来load 从表与之关联外键不变
例如:
Dept dept=(Dept)session.load(Dept.class, "4028803b230c3f0501230c3f08120001");
dept.setD_name("就业5");
session.update(dept);

问题:如何通过一的一方修改多的一方中的一条?
要点:本质上说hibernate的关系都存在set中,那么无论什么操作都可以通过set来级联的
本问题就是一例,如果修改中间表的一条,那么只需要把一的一方的set中的要修改的一条,查出来再修改最后updata一就可以了

相似的情况,如果要加一条,就在一的一方的set中加一条,最后update就可以了
记住,当要增加多的一方时,相当于对一的一方进行修改了

相似的情况,如果要修改一条,删除只能把关系删除,不能把多的一方删除,多的一方外变null

两种极限情况是:只修改一的一方
不修改一的一方,对多的一方即有添加又有修改还有删除,但是删除只能把关系删除,不能把多的一方删除,多的 一方外键变null

最复杂的请是:修改一的一方,多的一方即添加又有修改还有删除

例如:
Dept dept=(Dept)session.load(Dept.class, "4028803b230c3f0501230c3f08120001");
dept.setD_name("就业5");

Ren ren1=new Ren();
ren1.setR_name("小王5");

Iterator it=dept.getRenSet().iterator();
while(it.hasNext())
{
Ren r=(Ren)it.next();
if(r.getR_id().equals("4028803b230c3f0501230c3f08310002"))
{
it.remove();
}
}
dept.getRenSet().add(ren1);
session.update(dept);

(2)对于多的这一方的操作
概述:只要不涉及到外键的操作,就是单表的操作

增: 给外键的实体类,正常增
删: 正常删
改: 不改外键时,正常改
改外键时,new外键实体,给外键实体赋id,传给多的这一方的实体,在改

(3)关于onetomany实体配置的注意事项
一对多:埋实体不能new 埋set要new

2.manytomany

manytomany有两种配法: manytomany
两个onetomany

(1)manytomany
概述:
中间表没有表的实体类和配置文件
中间表仅有两个字段,分别是两边表的各自主键
两边表配置的时候,互相埋一个set来装对方实体
两边表可以操作中间表
中间没有单独的操作,只能被两边表的对set操作来操作

配置:两边表互相埋一个set来装对方实体
例如:

Teacher实体类

private String tid;
private String name;
private Set courseSet = new HashSet();

Teacher配置文件

<id name="tid" column="tid">
<generator class="uuid.hex"/>
</id>

<property name="name" column="name" type="string" length="50" not-null="false" />

<set name="courseSet" table="mid">
<key column="tid" />
<many-to-many class="middle.entity.Course" column="cid"/>
</set>

--------------------------------------------------

Course类

private String cid;
private String cname;
private Set teacherSet = new HashSet();

Course配置文件

<id name="cid" column="cid">
<generator class="uuid.hex"/>
</id>

<property name="cname" column="cname" type="string" length="50" not-null="false" />

<set name="teacherSet" table="mid">
<key column="cid" />
<many-to-many class="middle.entity.Teacher" column="tid"/>
</set>

增:类似一对多,在任意一边的表中的set里装另一方最后在Save就可以了
例如:
public void saveTeacher_kc(Teacher t,String []kc){
for (int i = 0; i < kc.length; i++) {
Course c = new Course();
c.setCid(kc[i]);
t.getCourseSet().add(c);
}
dao.save(t);
}

删除:由于两边表可以操作中间表,所以删除两边表的一方,中间表与之对应的就都删除了
public void deleteTeacher_kc(String ids[]){
for (int i = 0; i < ids.length; i++) {
Teacher t1 = (Teacher)dao.queryById(ids[i]);
dao.delete(t1);
}
}

修改:本质--set里有什么,中间表里就有什么
技巧--一般来说,先要把中间表中已有的记录都清除,在一次性的重新给值,这样便于操作
具体实现--把某一方的set给clear()了,在给set执行add()添加一些新的记录,最后update
例如:
public void editTeacher_kc(String id ,String name , String []kc){
Teacher teacher = (Teacher)dao.queryById(id);
teacher.getCourseSet().clear();
teacher.setName(name);
if(kc!=null){
for (int i = 0; i < kc.length; i++) {
Course course = new Course();
course.setCid(kc[i]);
teacher.getCourseSet().add(course);
}
}
}

(2)两个onetomany
概述:本质上就是一对多,所有的操作就是一对多
配置时,中间有自己的表实体和配置文件
中间表中除了有两边表的外间外,还可以有自己的主键和自己的字段
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: