一對多關聯映射(one-to-many)
一對多關聯映射利用了多對一關聯映射原理
* 多對一關聯映射:在多的一端加和一個外鍵指向一的一端,它維護的關系是多指向一的
* 一對多關聯映射:在一的一端加和一個外鍵指向多的一端,它維護的關系是一指向多的
也就是說一對多和多對一的映射策略是一樣的,只是站的角度不同,一般都作成雙項的
------------------------------------------------------------------------------
1 一對多關聯映射(單項Classes--->Student)
在一一端維護關系的缺點:
* 如果將t_student表里的classesid這段設置為非空,則無法保存
* 因為不在student這一端維護關系,所以student不知道是哪個班的
所以需要發出多余的update語句來更新關系
<!--
Classes: Student:
private int id; private int id;
private String name; private String name;
private Set students;//必須用Set
-->
<class name="com.my.hibernate.Student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>

<class name="Classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>

public void testSave1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Student student1=new Student();
student1.setName("10");
session.save(student1);//先進行save操作
Student student2=new Student();
student2.setName("祖兒");
session.save(student2);//先進行save操作
Set students=new HashSet();
students.add(student1);
students.add(student2);
Classes classes=new Classes();
classes.setName("尚學堂");
classes.setStudents(students);
session.save(classes);
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testLoad1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Classes classes=(Classes)session.load(Classes.class, 3);
System.out.println(classes.getName());
Set students=classes.getStudents();

for(Iterator iter=students.iterator();iter.hasNext();)
{
Student student=(Student)iter.next();
System.out.print(student.getName()+";");
}
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}
2 一對多關聯映射(雙項Classes<--->Student)
一對多雙向關聯映射:
* 在一一端的集合上用<key>,在對方表中加入一個外鍵指向一的一端
* 在多的一端采用<many-to-one>
注意:<key>標簽指定的外鍵字段必須和<many-to-one>指定的外鍵字段一致,否則引用字段錯誤
如果在一的一端維護一對多關聯關系,hibernate會發出多余的update語句,所以我們一般在多的一端來維護關聯關系
關于inverse屬性:
inverse主要用在一對多和多對多雙向關聯上,inverse可以被設置到集合標簽<set>上,
默認inverse為 false,所以我們可以從一的一端和多的一端維護關聯關系,
如果設inverse為true,則我們只能從多的一端來維護關聯關系
注意:inverse屬性,只影響數據的存儲,也就是持久化。
inverse和cascade:
* inverse是關聯關系的控制方向
* cascade是操作上的連鎖反應
<!--
Classes: Student:
private int id; private int id;
private String name; private String name;
private Set students;//必須用 Set private Classes classes;
-->
<class name="Classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true" cascade="all">
//cascade屬性:none 不及連 save-update 插入或更新及連 delete刪除及連 all
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>

<class name="com.my.hibernate.Student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid" cascade="save-update"/>
</class>


public void testSave1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
//在多方維護
Classes classes=new Classes();
classes.setName("北青");
//session.save(classes);//加了cascade屬性可以不用
Student student1=new Student();
student1.setName("黃不接10");
student1.setClasses(classes);
session.save(student1);
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testLoad1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
//從多方讀取
Student student=(Student)session.load(Student.class, 5);
System.out.println(student.getName());
System.out.println(student.getClasses().getName());
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testSave2()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
//在一方維護,自動轉向多方
Classes classes=new Classes();
classes.setName("尚學堂");
Student student1=new Student();
student1.setName("10");
student1.setClasses(classes);
Student student2=new Student();
student2.setName("祖兒");
student2.setClasses(classes);
Set students=new HashSet();
students.add(student1);
students.add(student2);
classes.setStudents(students);
session.save(classes);
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}
多對多關聯映射(單項User---->Role)
<many-to-many/>標簽
<set>標簽中加入屬性table="t_user_role"創建關聯表
<!--
User: Role:
private int id; private int id;
private String name; private String name;
private Set roles;
-->
<class name="com.my.hibernate.Role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>

<class name="User">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="userid"/>
<many-to-many class="Role" column="roleid"/>
</set>
</class>

public void testSave1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Role role1=new Role();
role1.setName("1111");
Role role2=new Role();
role2.setName("2222");
Role role3=new Role();
role3.setName("3333");
session.save(role1);
session.save(role2);
session.save(role3);
User user1=new User();
user1.setName("user1");
Set user1Role=new HashSet();
user1Role.add(role1);
user1Role.add(role2);
user1.setRoles(user1Role);
User user2=new User();
user2.setName("user2");
Set user2Role=new HashSet();
user2Role.add(role2);
user2Role.add(role3);
user2.setRoles(user2Role);
User user3=new User();
user3.setName("user3");
Set user3Role=new HashSet();
user3Role.add(role2);
user3Role.add(role3);
user3Role.add(role1);
user3.setRoles(user3Role);
session.save(user1);
session.save(user2);
session.save(user3);
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}

public void testLoad1()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
User u1=(User)session.load(User.class, 1);
System.out.println(u1.getName());

for(Iterator iter=u1.getRoles().iterator();iter.hasNext();)
{
System.out.println(((Role)iter.next()).getName());
}
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}
多對多關聯映射(雙項User<---->Role)
<many-to-many/>標簽
映射方法:
<set name="users" table="t_user_role" order-by="userid">
<key column="roleid"/>
<many-to-many class="com.my.hibernate.User" column="userid"/>
</set>
table屬性值必須和單向關聯的table屬性值一致
<key>中column屬性值要與單向關聯中的<many-to-many>標簽中的column屬性值一致
<many-to-many>中column屬性值要與單向關聯中的<key>標簽中的column屬性值一致
<!--
User: Role:
private int id; private int id;
private String name; private String name;
private Set roles; private Set users;
-->
<class name="com.my.hibernate.Role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="users" table="t_user_role" order-by="userid">
<key column="roleid"/>
<many-to-many class="com.my.hibernate.User" column="userid"/>
</set>
</class>
<class name="User">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="userid"/>
<many-to-many class="Role" column="roleid"/>
</set>
</class>

public void testLoad2()
{
Session session=null;

try
{
session=HibernateUtils.getSession();
session.beginTransaction();
Role role=(Role)session.load(Role.class, 3);
System.out.println(role.getName());

for(Iterator iter=role.getUsers().iterator();iter.hasNext();)
{
System.out.println(((User)iter.next()).getName());
}
session.getTransaction().commit();

}catch(Exception e)
{
session.getTransaction().rollback();
e.printStackTrace();

}finally
{
HibernateUtils.closeSession(session);
}
}
set 不可重復
posted on 2009-11-03 16:04
junly 閱讀(654)
評論(0) 編輯 收藏 所屬分類:
hibernate/orm