Hibernate实体关系映射—Annotation

hibernate实体关系映射分为:

    单边一对一,双边一对一;

    单边一对多,单边多对一;

    双边一对多,双边多对一;

    单边多对多,双边多对多;

    以及主键相同的单双边一对一。下面分别总结这几种关系映射的注解方法:

1.  单边一对一和双边一对一

    单边一对一:比如一个学生(Student)有一个学生证(StudentCard),且Student类中有一个StudentCard对象:

[java] view plain copy

 

  1. @Entity    
  2. @Table(name = "student")    
  3. public class Student {    
  4.     @Id    
  5.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  6.     private String id;    
  7.      
  8.     private String name;    
  9.      
  10.     @OneToOne(cascade = {CascadeType.ALL})    
  11.     @JoinColumn(name = "student_id", unique = true)    
  12.     private StudentCard stuCard;    
  13.      
  14.     //省略set,get方法,注解本应该放在get方法上,这里为了方便,放在成员变量上了。    
  15. }    
  16.      
  17. @Entity    
  18. @Table(name = "studentid")    
  19. public class StudentCard {    
  20.     @Id    
  21.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  22.     private String id;    
  23.      
  24.     private int num;    
  25. }   

    @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

 

  1. @Entity    
  2. public class Husband {    
  3.     @Id    
  4.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  5.     private int id;    
  6.      
  7.     private String name;    
  8.      
  9.     @OneToOne    
  10.     @JoinColumn(name="wifeId")//wifeId作为外键字段,关联wife表中的主键    
  11.     private Wife wife;    
  12. }    
  13.      
  14. @Entity    
  15. public class Wife {    
  16.     @Id    
  17.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  18.     private int id;    
  19.      
  20.     private String name;    
  21.      
  22.     @OneToOne(mappedBy = "wife")//表示已经在Husband类中对wife做了映射了。一般有双向关联的都要设置mappedBy     
  23.     private Husband husband;    
  24. }    

2. 单边一对多和单边多对一

    单边一对多:比如一个组(Group)里有多个用户(User),Group类中有存储User的集合:

[java] view plain copy

 

  1. @Entity    
  2. @Table(name="t_group")//group在sql中是关键词,避免冲突    
  3. public class Group {    
  4.     @Id    
  5.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  6.     private int id;    
  7.      
  8.     private String name;    
  9.      
  10.     @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)    
  11.     @JoinColumn(name="groupid")//表示t_user表中有个叫group_id的外键字段    
  12.     private Set<User> users = new HashSet<User>();    
  13. }    
  14.      
  15. @Entity    
  16. @Table(name="t_user")    
  17. public class User {    
  18.     @Id    
  19.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  20.     private int id;    
  21.      
  22.     private String name;    
  23. }    

    fetch属性有两个值:EAGER和LAZY。分别表示即时加载和延迟加载,这是ORM框架引入的概念。

        fetch = FetchType.LAZY表示加载group时不加载user,一般一对多的时候,在一方默认为LAZY,因为如果多方数据太多,会导致大量数据的加载,影响性能  

    单边多对一:比如一个组(Group)里有多个用户(User),User类中有Group类的成员变量:

[java] view plain copy

 

  1. @Entity    
  2. @Table(name="t_group")//group在sql中是关键词,避免冲突    
  3. public class Group {    
  4.     @Id    
  5.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  6.     private int id;    
  7.      
  8.     @Column(unique = true)//利用unique约束禁止重复数据    
  9.     private String name;    
  10. }    
  11.      
  12. @Entity    
  13. @Table(name="t_user")    
  14. public class User {    
  15.     @Id    
  16.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  17.     private int id;    
  18.      
  19.     private String name;    
  20.      
  21.     @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)    
  22.     @JoinColumn(name = "group_id")    
  23.     private Group group;    
  24. }    

   fetch = FetchType.EAGER表示加载user时加载group,多对一的时候,默认为EAGER

3. 双边一对多、多对一

    比如一个组(Group)里有多个用户(User),Group类中有存储User的集合,User类中有Group类的成员变量:

[java] view plain copy

 

  1. @Entity    
  2. @Table(name="t_group")    
  3. public class Group {    
  4.     @Id    
  5.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  6.     private int id;    
  7.      
  8.     private String name;    
  9.      
  10.     @OneToMany(mappedBy = "group")//表示已经在User类中对group做了映射了。一般有双向关联的都要设置mappedBy     
  11.     private Set<User> users = new HashSet<User>();    
  12. }    
  13.      
  14. @Entity    
  15. @Table(name="t_user")    
  16. public class User {    
  17.     @Id    
  18.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  19.     private int id;    
  20.      
  21.     private String name;    
  22.      
  23.     @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)    
  24.     @JoinColumn(name = "group_id")    
  25.     private Group group;    
  26. }    

    双边关系中,控制权一般交给多方,因此这里@OneToMany没有配置数据库的外键列,而只配置了一个mappyedBy属性,告诉Hibernate,配置信息要到Student类中的group属性中去找。 

4. 单边多对多和双边多对多

    单边多对多:比如老师(Teacher)有多个(Student),学生也有多个老师,但是只有Teacher类中有存储Student类的集合:

[java] view plain copy

 

  1. @Entity    
  2. public class Teacher {    
  3.     @Id    
  4.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  5.     private int id;    
  6.      
  7.     private String name;        
  8.      
  9.     @ManyToMany    
  10.     @JoinTable(    
  11.         name = "t_s",//第三张中间表名    
  12.         joinColumns = {@JoinColumn(name="teacher_id")},//第三张表中针对本表主键字段名称    
  13.         inverseJoinColumns = {@JoinColumn(name="student_id")}//第三张表中针对对方(student)表中主键名称    
  14.         )    
  15.     private Set<Student> students = new HashSet<Student>();    
  16. }    
  17.      
  18. @Entity    
  19. public class Student {    
  20.     @Id    
  21.     @GeneratedValue(strategy = GenerationType.IDENTITY)      
  22.     private int id;    
  23.      
  24.     private String name;    
  25. }    

    双边多对多只要在Student类中添加存储Teacher类的集合即可,并配有mappedBy属性。

[java] view plain copy

 

  1. @ManyToMany(mappedBy="students")    
  2. private Set<Teacher> teachers = new HashSet<Teacher>();    

5. 主键相同的单边一对一和双边一对一

    由于两个实体类是一对一的关系,因此可以设置两个实体类使用相同的主键。反过来,具有相同主键的实体被视为一对一的关系。

    针对上面一对一关系的例子,通过主键相同的方法如下:

    单边一对一:

[java] view plain copy

 

  1. @Entity    
  2. @Table(name = "student")    
  3. public class Student {    
  4.     @Id    
  5.     @GeneratedValue(strategy = GenerationType.IDENTITY)     
  6.     private String id;    
  7.      
  8.     private String name;    
  9.      
  10.     @OneToOne(cascade = {CascadeType.ALL})    
  11.     @PrimaryKeyJoinColumn    
  12.     private StudentCard stuCard;    
  13. }    
  14.      
  15. @Entity    
  16. @Table(name = "studentid")    
  17. public class StudentCard {    
  18.     @Id    
  19.     //这里不能使用自增长了     
  20.     private String id;    
  21.      
  22.     private int num;    
  23. }    

    双边一对一:

[java] view plain copy

 

  1. @Entity    
  2. public class Husband {    
  3.     @Id    
  4.     @GeneratedValue(strategy = GenerationType.IDENTITY)    
  5.     private int id;    
  6.      
  7.     private String name;    
  8.      
  9.     @OneToOne    
  10.     @PrimaryKeyJoinColumn    
  11.     private Wife wife;    
  12. }    
  13.      
  14. @Entity    
  15. public class Wife {    
  16.     @Id    
  17.     //这里不能使用自增长了     
  18.     private int id;    
  19.      
  20.     private String name;    
  21.      
  22.     @OneToOne    
  23.     @PrimaryKeyJoinColumn    
  24.     private Husband husband;    
  25. }    

        要注意的是save Husband和Wife的时候,先session.save(husband),在session.save(wife)之前要先设置wife的id和husband相同,即:wife.setId(husband.getId())  

        以上就是hibernate中实体关系映射的几种情况。如有错误,欢迎留言指正~

转载:http://blog.csdn.net/eson_15/article/details/51089666

时间: 2025-01-20 09:53:53

Hibernate实体关系映射—Annotation的相关文章

Java IDE 编辑器 --- IntelliJ IDEA 进阶篇 生成 hibernate 实体与映射文件

原文:转:Java IDE 编辑器 --- IntelliJ IDEA 进阶篇 生成 hibernate 实体与映射文件 2011-04-30 12:50         很多人不知道怎么用 IntelliJ IDEA 编辑器生成 Hibernate 实体映射文件,很多人认为 IDEA 不支持此功能,或者需要安装特定的插件才能完成该操作.实际上 IDEA 支持该功能也无需安装IntelliJ IDEA插件.          以下为 IntelliJ IDEA 编辑器生成 Hibernate 实

系统-hibernate的关系映射和无关系型数据库

问题描述 hibernate的关系映射和无关系型数据库 小白问个问题: 在hibernate中有多对一.一对一.一对多.多对多这样的关系,只要在hbm.xml文件中配置了,那么去生产数据表的时候就会给表创建外键 这个很好理解,但是我目前在开发中,我发现很多成熟的系统数据库并没有外键,而且架构师提倡不用外键来管理,这样hibernate的关系设计是不是就不符合现在系统设计得需要了? 解决方案 在数据库里可以不设主键或者外键来使用hibernate进行逻辑上的关联.架构师不提倡是因为在对数据库进行增

困惑多年的问题:关于实体关系映射

问题描述 在实体映射时请问应该怎么处理实体之前的关系.举个例子,实体A引用实体B,实体B又与实体C为一对多(或多对多)关系,如下:classEntityA{publicintEntityBId{get;set;}publicEntityBEntityB{get;set;}}classEntityB{publicList<EntityC>EntityCItems{get;set;}}classEntityC{}数据访问类classEntityADAL{EntityAGetByPK(intEnti

【HIBERNATE框架开发之七】HIBERNATE使用ANNOTATION中各种关系映射的CRUD(增删改查)&amp;&amp;集合映射&amp;&amp;继承映射

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/hibernate/822.html       首先对于Annotation中CRUD的C(Create)操作:-------- 假设 :   User (MonyToOne)       Group OK,那么有如下 Junit Code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Conf

Hibernate -- 注解(Annotation)关系映射

转自:http://www.cnblogs.com/tyler2000/archive/2011/01/20/1940354.html 1. Hibernate Annotation关系映射有下面几种类型:1)一对一外键关联映射(单向) 2)一对一外键关联映射(双向) 3)一对一主键关联映射(不重要)在这不演示 在实际中很少用,使用注解@PrimaryKeyJoinColumn 意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用 注解一对一主键关联映射,在生成表的时候,数

Hibernate及JPA 对象关系映射的简单映射策略

简单映射 近年来 ORM(Object-Relational Mapping,对象关系映射,即实体对象和数据库表的映射)技术市场 热闹非凡,各种各样的持久化框架应运而生,其中影响最大的是 Hibernate 和 Toplink.Sun 公司在充分吸收现有的优秀 ORM 尤其是 Hibernate 框架设计思想的基础上,制定了新的 JPA(Java Persistence API)规范,对现在乱象丛生的持久 化市场带来一个标准,大有统一持久化市场的气势.JPA 是通过 JDK5.0 注解或 XML

Hibernate及JPA对象关系映射:关联关系映射策略

关联关系映射 关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一.一对多和多对多几种 关系.细分起来他们又有单向和双向之分.下面我们逐一介绍一下. 单向 OneToOne 单向一对一是关联关系 映射中最简单的一种,简单地说就是可以从关联的一方去查询另一方,却不能反向查询.我们用下面的例子来举例说明,清 单 1 中的 Person 实体类和清单 2 中的 Address 类就是这种单向的一对一关系,我们可以查询一个 Person 的对应的 Address 的内容,但是我们却不能由一

第十章 基于Annotation的关系映射 一对一

如果下面部分内容有不明白的可以查找: 基于Annotation的关系映射 前期准备:http://blog.csdn.net/p_3er/article/details/9061911 基于映射文件共享主键方式实现一对一:http://blog.csdn.net/p_3er/article/details/9004419 基于映射文件唯一外键式实现一对一:http://blog.csdn.net/p_3er/article/details/9004471 1.共享主键方式: Person: @E

角色和权限Hibernate实体映射配置

角色实体 package cn.itcast.oa.domain; import java.util.HashSet; import java.util.Set; /**  * 岗位  *   * @author tyg  *   */ public class Role {     private Long id;     private String name;     private String description;     private Set<User> users = ne