在1和N之间的关系之间,由于一对多双向,多对一双向一回事,所以,1和N 之间的关系就只有三种。还有一点需要说明,不管是这三种映射中的哪一种,数据库表的级别来看,表结构应该是没有变化的,变化的只是我们的变成模型。以下代码以“用户组”和“用户”来讲解。
一:一对多单向
一对多,一般都是在一的一段放一个集合,存放一个多的一段,但是,这只是我们的编程模型,反映到数据库表中,还是在多的一段放置的外键来引用,这点一定注意区分。
1.1:Annotation方式:
Group.java:
@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OneToMany
@JoinColumn(name="groupId")//一对多单向,如果不加这个注解,默认将会按照多对多单向处理,因而会出现中间表!
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
一定注意加@JoinColumn。
User.java:
@Entity
@Table(name="t_user")
public class User {
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;
}
}
测试输出代码建表代码:
15:47:46,298 DEBUG SchemaExport:377 -
create table t_group (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
15:47:46,300 ERROR SchemaExport:348 - Unsuccessful: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))
15:47:46,300 ERROR SchemaExport:349 - Table 't_group' already exists
15:47:46,300 DEBUG SchemaExport:377 -
create table t_user (
id integer not null auto_increment,
name varchar(255),
groupId integer,
primary key (id)
)
15:47:46,483 DEBUG SchemaExport:377 -
alter table t_user
add index FKCB63CCB6F44F22BD (groupId),
add constraint FKCB63CCB6F44F22BD
foreign key (groupId)
references t_group (id)
15:47:46,704 INFO SchemaExport:268 - schema export complete
观察代码:在多的一端(User)生成了一个外键groupId。
1.2:XML方式
由于只是在多的一端加入了一个集合,而一的一段,没有任何变化,所以,xml只是在多的一段加入了一个集合,而在一的一段没有任何关联信息设置。所以此处指写出一的一端xml文件:
<hibernate-mapping package="com.zxb.model">
<class name="Group" table="t_group">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" column="name" />
<set name="users">
<key column="group_id"></key>
<one-to-many class="User" />
</set>
</class>
</hibernate-mapping>
测试生成的代码和上面一样。
二:多对一单向
2.1:Annotation方式:
Group.java
@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.java:
@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;
}
@ManyToOne
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
发现,在配置多对一的时候,配置十分简单,只需要在多的一段加上一个@ManyToOne即可。 运行代码如下:
15:02:35,768 DEBUG SchemaExport:377 -
create table t_group (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
15:02:35,895 DEBUG SchemaExport:377 -
create table t_user (
id integer not null auto_increment,
name varchar(255),
group_id integer,
primary key (id)
)
15:02:35,939 DEBUG SchemaExport:377 -
alter table t_user
add index FKCB63CCB610039BE (group_id),
add constraint FKCB63CCB610039BE
foreign key (group_id)
references t_group (id)
15:02:36,028 INFO SchemaExport:268 - schema export complete
我们看到,数据库级别上我们的t_user表中生成了外键指向了t_group的主键。
2.2:XML方式
此种方式下,由于是单向,所以一的一段没有任何需要特殊配置的,只需要在多的一端通过many-to-one来配置关联即可。代码如下,测试生成的代码和上面一样,不在给出。<hibernate-mapping package="com.zxb.model">
<class name="User" table="t_user">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" column="name" />
<many-to-one name="group" column="group_id"></many-to-one>
</class>
</hibernate-mapping>
三:多对一双向
由于是双向,多以,在多的一端代码中要有一的一端的引用,在一的一端,要有包含多的一端的一个集合。但是,反映在数据库表中,数据库表依然只会在多的那一端加上一个外键来指向多的一端。
3.1:Annotation方式:
Group.java:
@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OneToMany(mappedBy="group")
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
一般而言,我们都会让多的一端控制关联关系,这里为了避免生成中间表,我们在@OneToMany中,使用mappedBy属性来制定,关联关系放到多的一端通过属性group来设置。
User.java:
@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;
}
@ManyToOne
@JoinColumn(name="groupId")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
测试代码见下XML方式
3.2:XML方式
此时,由于是双向的,所以,Gruop.hbm.xml和User.hbm.xml都需要改变,代码如下:
Group.hbm.xml:
<hibernate-mapping package="com.zxb.model">
<class name="Group" table="t_group">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" column="name" />
<set name="users" inverse="true">
<key column="groupId"></key>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>
User.hbm.xml:
<hibernate-mapping package="com.zxb.model">
<class name="User" table="t_user">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" column="name" />
<many-to-one name="group" column="groupId"></many-to-one>
</class>
</hibernate-mapping>
测试代码如下:
16:03:14,346 DEBUG SchemaExport:377 -
create table t_group (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
16:03:14,432 DEBUG SchemaExport:377 -
create table t_user (
id integer not null auto_increment,
name varchar(255),
groupId integer,
primary key (id)
)
16:03:14,488 DEBUG SchemaExport:377 -
alter table t_user
add index FKCB63CCB6F44F22BD (groupId),
add constraint FKCB63CCB6F44F22BD
foreign key (groupId)
references t_group (id)
16:03:14,655 INFO SchemaExport:268 - schema export complete