本文以组和用户为例,讲述hibernate中多对一关联关系的映射原理以及应用。
1.原理
在对象模型中,关联关系是有方向的。多对一顾名思义,维护关系的是多的一方。也就是本例中的用户的一方。此处我们只说单向关联。原理图如下:
对象模型上可以看出,由多的一方也就是User的一方来维护关系,而此时,对于Group对象来说,根本不知道User对象的存在;从关系模型上可以看出,在多的一方也就是user表中,加入了一个字段groupid,来引用一的一方。
2.基于xml的映射配置
我们来看代码,先建立Group类:
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;
}
}
Group类的映射文件:
<hibernate-mapping>
<class name="Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
再来看User类的代码:
public class User {
private int id;
private String name;
//User对象持有Group对象的引用,从对象模型上看,该属性必须存在
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对象的映射文件:
<hibernate-mapping>
<class name="User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!--该标签用来维护关联关系,column属性指定了关联字段的名称-->
<many-to-one name="group" column="groupid"/>
</class>
</hibernate-mapping>
下面我们来测试一下:
@Test
public void testSave1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Group group = new Group();
group.setName("第一组");
User user1 = new User();
user1.setName("张三");
user1.setGroup(group);
User user2 = new User();
user2.setName("李四");
user2.setGroup(group);
session.save(user1);
session.save(user2);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
运行之后发现报错了,报了TransientObjectException,是因为在保存用户的时候,组并不存在。那在保存用户的时候先保存组就可以了。
3.基于JPA的映射配置
先看Group类的代码:
@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
@Id
@GeneratedValue
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类的代码:
@Entity
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group;
@Id
@GeneratedValue
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;
}
//默认会生成字段名,规则是:属性名_id
//用JoinColumn来自定义外键的名称
@ManyToOne
@JoinColumn("group_id")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
下来测试一下:
扫描二维码关注公众号,回复:
1903278 查看本文章
public void testSave2() {
Session session = null;
try {
session = HibernateUtils4Xml.getSession();
session.beginTransaction();
Group group = new Group();
group.setName("Jpa组");
session.save(group);
User user1 = new User();
user1.setName("张三");
user1.setGroup(group);
User user2 = new User();
user2.setName("李四");
user2.setGroup(group);
session.save(user1);
session.save(user2);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils4Xml.closeSession(session);
}
}
可以保存成功!发出的sql语句如下:
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (group_id, name) values (?, ?)
Hibernate: insert into t_user (group_id, name) values (?, ?)
ok, 以上就是hibernate多对一的讲解,源代码请看:https://github.com/maodou95838/hibernate_many2one,谢谢大家。