Hibernate实体关系映射—Annotation
2017-03-02 16:35
489 查看
转载自 Hibernate实体关系映射—Annotation
hibernate实体关系映射分为:
单边一对一,双边一对一;
单边一对多,单边多对一;
双边一对多,双边多对一;
单边多对多,双边多对多;
以及主键相同的单双边一对一。下面分别总结这几种关系映射的注解方法:
1. 单边一对一和双边一对一
单边一对一:比如一个学生(Student)有一个学生证(StudentCard),且Student类中有一个StudentCard对象:
[java]
view plain
copy
print?
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "student_id", unique = true)
private StudentCard stuCard;
//省略set,get方法,注解本应该放在get方法上,这里为了方便,放在成员变量上了。
}
@Entity
@Table(name = "studentid")
public class StudentCard {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private int num;
}
@GeneratedValue表示主键自增长类型,有AUTO, TABLE, SEQUENCE, IDENTITY四种方式:
GenerationType.AUTO:自动方式,根据底层数据库自动选择;
GenerationType.TABLE:使用指定的表来决定主键的取值,一般结合@TableGenerator使用;
GenerationType.SEQUECE:使用Sequece来决定主键的取值,适合Oracle、DB2、PostgreSQL、SAP
DB等支持Sequence的数据库,一般结合@SequenceGnerator使用;
GenerationType.IDENTITY:支持DB2、MySQL、MS
SQL Server、Sybase与HypersonicSQL数据库的identity类型主键。
@OneToOne表示一对一,cascade配置级联方式,有PERSIST、REMOVE、MERGE、REFRESH等几种取值,分别表示在保存、删除、修改、刷新Student类时,会自动在数据库
中保存、删除、修改、刷新属于它的StudentCard对象,ALL则表示所有动作皆级联。即级联后可以通过操作Student类来操作StudentCard类。
双边一对一:比如丈夫(Husband)和妻子(Wife),每个类中皆有对方的类对象:
[java]
view plain
copy
print?
@Entity
public class Husband {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne
@JoinColumn(name="wifeId")//wifeId作为外键字段,关联wife表中的主键
private Wife wife;
}
@Entity
public class Wife {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne(mappedBy = "wife")//表示已经在Husband类中对wife做了映射了。一般有双向关联的都要设置mappedBy
private Husband husband;
}
[java]
view plain
copy
print?
@Entity
@Table(name="t_group")//group在sql中是关键词,避免冲突
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name="groupid")//表示t_user表中有个叫group_id的外键字段
private Set<User> users = new HashSet<User>();
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
fetch = FetchType.LAZY表示加载group时不加载user,一般一对多的时候,在一方默认为LAZY,因为如果多方数据太多,会导致大量数据的加载,影响性能
单边多对一:比如一个组(Group)里有多个用户(User),User类中有Group类的成员变量:
[java]
view plain
copy
print?
@Entity
@Table(name="t_group")//group在sql中是关键词,避免冲突
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true)//利用unique约束禁止重复数据
private String name;
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "group_id")
private Group group;
}
[java]
view plain
copy
print?
@Entity
@Table(name="t_group")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(mappedBy = "group")//表示已经在User类中对group做了映射了。一般有双向关联的都要设置mappedBy
private Set<User> users = new HashSet<User>();
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "group_id")
private Group group;
}
[java]
view plain
copy
print?
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany
@JoinTable(
name = "t_s",//第三张中间表名
joinColumns = {@JoinColumn(name="teacher_id")},//第三张表中针对本表主键字段名称
inverseJoinColumns = {@JoinColumn(name="student_id")}//第三张表中针对对方(student)表中主键名称
)
private Set<Student> students = new HashSet<Student>();
}
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
[java]
view plain
copy
print?
@ManyToMany(mappedBy="students")
private Set<Teacher> teachers = new HashSet<Teacher>();
针对上面一对一关系的例子,通过主键相同的方法如下:
单边一对一:
[java]
view plain
copy
print?
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
@OneToOne(cascade = {CascadeType.ALL})
@PrimaryKeyJoinColumn
private StudentCard stuCard;
}
@Entity
@Table(name = "studentid")
public class StudentCard {
@Id
//这里不能使用自增长了
private String id;
private int num;
}
双边一对一:
[java]
view plain
copy
print?
@Entity
public class Husband {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne
@PrimaryKeyJoinColumn
private Wife wife;
}
@Entity
public class Wife {
@Id
//这里不能使用自增长了
private int id;
private String name;
@OneToOne
@PrimaryKeyJoinColumn
private Husband husband;
}
要注意的是save Husband和Wife的时候,先session.save(husband),在session.save(wife)之前要先设置wife的id和husband相同,即:wife.setId(husband.getId())
以上就是hibernate中实体关系映射的几种情况。如有错误,欢迎留言指正~
_____________________________________________________________________________________________________________________________________________________
-----乐于分享,共同进步!
-----更多文章请看:http://blog.csdn.net/eson_15
hibernate实体关系映射分为:
单边一对一,双边一对一;
单边一对多,单边多对一;
双边一对多,双边多对一;
单边多对多,双边多对多;
以及主键相同的单双边一对一。下面分别总结这几种关系映射的注解方法:
1. 单边一对一和双边一对一
单边一对一:比如一个学生(Student)有一个学生证(StudentCard),且Student类中有一个StudentCard对象:[java]
view plain
copy
print?
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "student_id", unique = true)
private StudentCard stuCard;
//省略set,get方法,注解本应该放在get方法上,这里为了方便,放在成员变量上了。
}
@Entity
@Table(name = "studentid")
public class StudentCard {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private int num;
}
@Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private String id; private String name; @OneToOne(cascade = {CascadeType.ALL}) @JoinColumn(name = "student_id", unique = true) private StudentCard stuCard; //省略set,get方法,注解本应该放在get方法上,这里为了方便,放在成员变量上了。 } @Entity @Table(name = "studentid") public class StudentCard { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private String id; private int num; }@Table中name属性表示指定实体对应 的表名,可以不指定。
@GeneratedValue表示主键自增长类型,有AUTO, TABLE, SEQUENCE, IDENTITY四种方式:
GenerationType.AUTO:自动方式,根据底层数据库自动选择;
GenerationType.TABLE:使用指定的表来决定主键的取值,一般结合@TableGenerator使用;
GenerationType.SEQUECE:使用Sequece来决定主键的取值,适合Oracle、DB2、PostgreSQL、SAP
DB等支持Sequence的数据库,一般结合@SequenceGnerator使用;
GenerationType.IDENTITY:支持DB2、MySQL、MS
SQL Server、Sybase与HypersonicSQL数据库的identity类型主键。
@OneToOne表示一对一,cascade配置级联方式,有PERSIST、REMOVE、MERGE、REFRESH等几种取值,分别表示在保存、删除、修改、刷新Student类时,会自动在数据库
中保存、删除、修改、刷新属于它的StudentCard对象,ALL则表示所有动作皆级联。即级联后可以通过操作Student类来操作StudentCard类。
双边一对一:比如丈夫(Husband)和妻子(Wife),每个类中皆有对方的类对象:
[java]
view plain
copy
print?
@Entity
public class Husband {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne
@JoinColumn(name="wifeId")//wifeId作为外键字段,关联wife表中的主键
private Wife wife;
}
@Entity
public class Wife {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne(mappedBy = "wife")//表示已经在Husband类中对wife做了映射了。一般有双向关联的都要设置mappedBy
private Husband husband;
}
@Entity public class Husband { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToOne @JoinColumn(name="wifeId")//wifeId作为外键字段,关联wife表中的主键 private Wife wife; } @Entity public class Wife { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToOne(mappedBy = "wife")//表示已经在Husband类中对wife做了映射了。一般有双向关联的都要设置mappedBy private Husband husband; }
2. 单边一对多和单边多对一
单边一对多:比如一个组(Group)里有多个用户(User),Group类中有存储User的集合:[java]
view plain
copy
print?
@Entity
@Table(name="t_group")//group在sql中是关键词,避免冲突
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name="groupid")//表示t_user表中有个叫group_id的外键字段
private Set<User> users = new HashSet<User>();
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
@Entity @Table(name="t_group")//group在sql中是关键词,避免冲突 public class Group { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY) @JoinColumn(name="groupid")//表示t_user表中有个叫group_id的外键字段 private Set<User> users = new HashSet<User>(); } @Entity @Table(name="t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; }fetch属性有两个值:EAGER和LAZY。分别表示即时加载和延迟加载,这是ORM框架引入的概念。
fetch = FetchType.LAZY表示加载group时不加载user,一般一对多的时候,在一方默认为LAZY,因为如果多方数据太多,会导致大量数据的加载,影响性能
单边多对一:比如一个组(Group)里有多个用户(User),User类中有Group类的成员变量:
[java]
view plain
copy
print?
@Entity
@Table(name="t_group")//group在sql中是关键词,避免冲突
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true)//利用unique约束禁止重复数据
private String name;
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "group_id")
private Group group;
}
@Entity @Table(name="t_group")//group在sql中是关键词,避免冲突 public class Group { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(unique = true)//利用unique约束禁止重复数据 private String name; } @Entity @Table(name="t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER) @JoinColumn(name = "group_id") private Group group; }fetch = FetchType.EAGER表示加载user时加载group,多对一的时候,默认为EAGER
3. 双边一对多、多对一
比如一个组(Group)里有多个用户(User),Group类中有存储User的集合,User类中有Group类的成员变量:[java]
view plain
copy
print?
@Entity
@Table(name="t_group")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToMany(mappedBy = "group")//表示已经在User类中对group做了映射了。一般有双向关联的都要设置mappedBy
private Set<User> users = new HashSet<User>();
}
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinColumn(name = "group_id")
private Group group;
}
@Entity @Table(name="t_group") public class Group { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToMany(mappedBy = "group")//表示已经在User类中对group做了映射了。一般有双向关联的都要设置mappedBy private Set<User> users = new HashSet<User>(); } @Entity @Table(name="t_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER) @JoinColumn(name = "group_id") private Group group; }双边关系中,控制权一般交给多方,因此这里@OneToMany没有配置数据库的外键列,而只配置了一个mappyedBy属性,告诉Hibernate,配置信息要到Student类中的group属性中去找。
4. 单边多对多和双边多对多
单边多对多:比如老师(Teacher)有多个(Student),学生也有多个老师,但是只有Teacher类中有存储Student类的集合:[java]
view plain
copy
print?
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany
@JoinTable(
name = "t_s",//第三张中间表名
joinColumns = {@JoinColumn(name="teacher_id")},//第三张表中针对本表主键字段名称
inverseJoinColumns = {@JoinColumn(name="student_id")}//第三张表中针对对方(student)表中主键名称
)
private Set<Student> students = new HashSet<Student>();
}
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
@Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @ManyToMany @JoinTable( name = "t_s",//第三张中间表名 joinColumns = {@JoinColumn(name="teacher_id")},//第三张表中针对本表主键字段名称 inverseJoinColumns = {@JoinColumn(name="student_id")}//第三张表中针对对方(student)表中主键名称 ) private Set<Student> students = new HashSet<Student>(); } @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; }双边多对多只要在Student类中添加存储Teacher类的集合即可,并配有mappedBy属性。
[java]
view plain
copy
print?
@ManyToMany(mappedBy="students")
private Set<Teacher> teachers = new HashSet<Teacher>();
@ManyToMany(mappedBy="students") private Set<Teacher> teachers = new HashSet<Teacher>();
5. 主键相同的单边一对一和双边一对一
由于两个实体类是一对一的关系,因此可以设置两个实体类使用相同的主键。反过来,具有相同主键的实体被视为一对一的关系。针对上面一对一关系的例子,通过主键相同的方法如下:
单边一对一:
[java]
view plain
copy
print?
@Entity
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String name;
@OneToOne(cascade = {CascadeType.ALL})
@PrimaryKeyJoinColumn
private StudentCard stuCard;
}
@Entity
@Table(name = "studentid")
public class StudentCard {
@Id
//这里不能使用自增长了
private String id;
private int num;
}
@Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private String id; private String name; @OneToOne(cascade = {CascadeType.ALL}) @PrimaryKeyJoinColumn private StudentCard stuCard; } @Entity @Table(name = "studentid") public class StudentCard { @Id //这里不能使用自增长了 private String id; private int num; }
双边一对一:
[java]
view plain
copy
print?
@Entity
public class Husband {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne
@PrimaryKeyJoinColumn
private Wife wife;
}
@Entity
public class Wife {
@Id
//这里不能使用自增长了
private int id;
private String name;
@OneToOne
@PrimaryKeyJoinColumn
private Husband husband;
}
@Entity public class Husband { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; @OneToOne @PrimaryKeyJoinColumn private Wife wife; } @Entity public class Wife { @Id //这里不能使用自增长了 private int id; private String name; @OneToOne @PrimaryKeyJoinColumn private Husband husband; }
要注意的是save Husband和Wife的时候,先session.save(husband),在session.save(wife)之前要先设置wife的id和husband相同,即:wife.setId(husband.getId())
以上就是hibernate中实体关系映射的几种情况。如有错误,欢迎留言指正~
_____________________________________________________________________________________________________________________________________________________
-----乐于分享,共同进步!
-----更多文章请看:http://blog.csdn.net/eson_15
相关文章推荐
- Hibernate实体关系映射—Annotation
- Hibernate实体关系映射—Annotation
- Hibernate -- 注解(Annotation)关系映射
- hibernate关系映射小结 - annotation
- hibernate annotation注解方式来处理映射关系
- Hibernate -- 注解(Annotation)关系映射
- 4、Hibernate 实体关系映射(一、单边一对多关系 注解、xml两种方式)
- Hibernate之关系映射的两种方式(xml映射、annotation注解映射)
- Hibernate实体关系映射:单向主键一对一关联
- Hibernate -- 注解(Annotation)关系映射
- 怎么在Hibernate实体间建立映射关系
- Hibernate -- 注解(Annotation)关系映射
- Hibernate实体关系映射
- Hibernate Annotation关系映射, 级联cascade属性
- hibernate annotation注解方式来处理映射关系
- Hibernate关系映射(四)一对多单向关联@OneToMany Annotation方式
- Hibernate Annotation关系映射的几种类型映射用法及使用方法
- Hibernate两种实体关系映射详解
- Hibernate实体关系映射——单边的多对多关系
- hibernate annotation注解方式来处理映射关系