一对多关联映射(单向关联)见项目:me_one_to_many
1.
模型
一个用户组(group)对应多个用户。
2.
实体类(省略set,get方法)
public class User { private int id; private String name; } public class Group { private int id; private String name; private Set Users; }
3.
数据模型
mysql> desc t_user;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| groupid | int(11) | YES | MUL | NULL | |
+---------+--------------+------+-----+---------+----------------+
mysql> desc t_group;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
4.
映射文件
一个用户组对应多个用户。
多对一关联映射:是在"多"的一端添加一个外键指向"一"的一端,它维护的关系为多到一的关系,如:当载入一个用户(user)时将载入组(group)的信息。
一对多关联映射:是在"多"的一端添加一个外键指向"一"的一端,它维护的关系为一到多的关系,如:当载入一个组(group)时将载入此组用户的信息。
可以说,一对多和多对一的映射策略是一致的,都是通过在"多"的一端添加一个外键指向"一"的一端,只是站的角度不同。
User.hbm.xml:
<hibernate-mapping> <class name="com.dvnchina.hibernate.User" table="t_user"> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
Group.hbm.xml:
<hibernate-mapping> <class name="com.dvnchina.hibernate.Group" table="t_group"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <!-- <set name="users" cascade="all">--> <set name="users" order-by="name"> <key column="groupid"/> <one-to-many class="com.dvnchina.hibernate.User"/> </set> </class> </hibernate-mapping>
5.
测试
public class TestOneToMany extends TestCase { public void testSave(){ Session session = HibernateUtils.getSession(); Transaction tx = session.beginTransaction(); Set<User> users = new HashSet<User>(); for(int i=0;i<9;i++){ User user = new User(); user.setName("yang"+i); //session.save(user); users.add(user); } //当user没有save,即为Transient对象,将抛出TransientObjectException //因为持久对象不能直接引用瞬时对象,所以我们需要先save(user)使其为持久对象后 //再引用 Group group = new Group(); group.setName("凤山人在线"); group.setUsers(users); session.save(group); tx.commit(); HibernateUtils.closeSession(session); } public void testCascade(){ Session session = HibernateUtils.getSession(); Transaction tx = session.beginTransaction(); Set<User> users = new HashSet<User>(); for(int i=0;i<9;i++){ User user = new User(); user.setName("yang"+i); users.add(user); } //在user.hbm.xml中的one-to-many中设置级联设置cascade="all",此时不需要使user //为持久对象而可以直接使用它,因为save(group)时将级联保存user Group group = new Group(); group.setName("凤山人在线"); group.setUsers(users); session.save(group); tx.commit(); HibernateUtils.closeSession(session); } //级联是对象之间的连锁操作(只对增删改起作用,对load不起作用,load是由one-to-many维护的) public void testLoad(){ Session session = HibernateUtils.getSession(); Transaction tx = session.beginTransaction(); Group group = (Group) session.load(Group.class, 2); Set list = group.getUsers(); for(Iterator ite = list.iterator();ite.hasNext();){ User user = (User) ite.next(); System.out.println(group.getName()+","+user.getName()); } tx.commit(); HibernateUtils.closeSession(session); } }