今天试着写了一个hibernate的关联映射,关系是一对多。
写了两个实体类,Group 和User。
Group.java文件:
package com.mp.hibernate;
public class Group {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
User.java文件:
package com.mp.hibernate;
import java.util.Date;
public class User {
private int id;
private String name;
private Group group;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
在这两个对象关系中通过User持有Group对象来表明两者之间的多对一的关系,那么如何来配置使得hibernet能认识他们的关系呢?
那么来看一下Group.hbm.xml和User.hbm.xml这两个文件如何来写吧:
Group.hbm.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.mp.hibernate.Group" table="t_group"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> </class> </hibernate-mapping>
User.hbm.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.mp.hibernate.User" table="t_user"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <many-to-one name="group" column="groupid"></many-to-one> </class> </hibernate-mapping>
其中在这里的核心配置就是
<many-to-one name="group" column="groupid"></many-to-one>
这个配置,首先它配置在User中就是 属于many 方面,它的name属性指明了one是谁,
这两个配置文件中对对象的table都重新命名主要是防止出错,由于User里面的group与Group对象名字相同。
写了一个测试方法来测试现在能否完成对象的保存:
public void testSave1() {
Session session = null;
User user = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Group group = new Group();
group.setName("明星");
User u1 = new User();
u1.setName("刘德华");
u1.setGroup(group);
User u2 = new User();
u2.setName("陈小春");
u2.setGroup(group);
//仅保存user时不能成功保存,抛出TransientObjectException异常
//因为Group为Transient状态,O id没有分配值
//persistent状态对象是不能引用Transient状态的对象的
session.save(u1);
session.save(u2);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtils.closeSession(session);
}
}
用这个方法的的结果已经在代码中间的注释中说明了,这里就不再过多说明。
然后又在此基础上面添加了一句就是:
session.save(group);
这样就能看到效果了:
表中user 的id 是3 和 4 是由于第一次存储的时候出错了,已经自增过了。
这样算是成功了,但是感觉还不是那么完善似的,就看看还有没有其他的方法了
这时就想到数据的级联了,看看hibernate的配置中能不能配置级联关系呢?
答案是可以。
将<many-to-one name="group" column="groupid" ></many-to-one> 改为
<many-to-one name="group" column="groupid" cascade="all"></many-to-one>
cascade就是级联操作的意思,它主要级联sava 、update、delete操作。在这里本来是不能级联delete操作的,简单起见就把它的值定义成了all
然后还是用以前的那个没有加
session.save(group);的方法,看是不是能保存成功呢?
结果是这样的:
说明保存成功了。
完成时,在逻辑上面考虑了一下,觉得还是加上group 的save操作比较好,这样在逻辑上面也比较好理解。