• hibernate之数据库注解关联关系


    一、           单项N-1关联

    在单项关联和双向关联,都需要在N的一段使用@ManyToOne修饰关联实体的属性。

    @ManyToOne支持的属性

    属性

    是否必须

    说明

    cascade

    指定Hibernate对关联实体采样怎样的级联策略

    CascadeType.ALL:Hibernate将所有的持久化操作都级联到关联实体

    CascadeType.MERGE:Hibernate将merge操作级联到关联实体

    CascadeType.PERSIST: Hibernate将persist操作级联到关联实体

    CascadeType.REFRESH: Hibernate将refresh操作级联到关联实体

    CascadeType.REMOVE: Hibernate将remove操作级联到关联实体

    fetch

    指定抓取关联实体时的抓取策略,

    FetchType.EAGER:立即抓取关联实体,默认

    FetchType.LAZY: 延迟抓取关联实体。真正用到关联实体才抓取

    optional

    关联关系是否可选

    targetEntity

    指定关联实体的类名。默认情况下将通过反射来判断关联实体的类名

    使用注意:在@OneToMany、@ManyToMany修饰的1-N、N-N关联中,关联实体的Set集合不带泛型信息,必须指定此属性

    1.    无连接表的N-1关联

    @Entity

    @Table(name="address_inf")

    public class Address {

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

    }

    public class Person {

     

      

       //标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

       @ManyToOne(targetEntity=Address.class)

       //映射外键列,指定外键列的列名为address_id,不允许为空

       @JoinColumn(name="address_id",nullable=false)

       @Cascade(CascadeType.ALL)

       private Address address;

       }

    2.    有连接表的N-1关联

    使用连接表来映射单项N-1关联,程序需要显式使用@JoinTable注解来映射连接属性

    @JoinTable支持的属性

    属性

    是否必须

    说明

    name

    指定链接表表明

    catalog

    将连接表放入指定catalog中。没有指定该属性则放入默认catalog中

    schema

    将连接表放入指定schema中。没有指定该属性则放入默认schema中

    targetEntity

    指定关联实体类名,默认情况下通过反射来判断关联实体类名

    indexes

    @Index注解数组,为连接表定义多个索引

    joinColumns

    可接受多个@JoinColumn,用于配置连接表中外键列的列信息,这些外键列参照当前实体对应表的主键列

    inverseJoinColumns

    接受多个@JoinColumn,用于配置链接表中外键列信息,这些外键列参照当前实体的关联实体对应的主键列

    uniqueConstrains

    为链接表增加唯一约束

    Class Person{

           //标识属性

         @Id @Column(name="person_id")

         @GeneratedValue(strategy=GenerationType.IDENTITY)

         private Integer id;

         //定义该Person实体关联的Address实体

         @ManyToOne(targetEntity=Address.class)

         //显式使用@JoinTable映射连接表

         @JoinTable(name="person_address",//指定链接表的表名为person_address

         //指定链接表中person_id外键列,参照当前实体对应表的主键列

         joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

         //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列

         inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id")

         )

     

         private Address address;

    }

    二、           单向1-1关联

    对于1-1关联 单/双项关联需要使用@OneToOne修饰代表关联实体的属性

    @OneToOne支持的属性

    属性

    是否必须

    说明

    cascade

    指定Hibernate对关联实体采样怎样的级联策略

    CascadeType.ALL:Hibernate将所有的持久化操作都级联到关联实体

    CascadeType.MERGE:Hibernate将merge操作级联到关联实体

    CascadeType.PERSIST: Hibernate将persist操作级联到关联实体

    CascadeType.REFRESH: Hibernate将refresh操作级联到关联实体

    CascadeType.REMOVE: Hibernate将remove操作级联到关联实体

    tetch

    指定抓取关联实体时的抓取策略,

    FetchType.EAGER:立即抓取关联实体,默认

    FetchType.LAZY: 延迟抓取关联实体。真正用到关联实体才抓取

    MappedBy

    该属性合法的属性值为关联实体的属性名,该属性指定关联实体中哪个属性可引用到当前实体

    orphanRemoval

    该属性设置是否删除孤儿实体。如果某个实体所关联的父实体不存在(既实体对应记录的外键为null),该实体就是所谓的孤儿实体

    optional

    关联关系是否可选

    targetEntity

    指定关联实体的类名。默认通过反射来判断关联实体名

    1)    基于外键的单项1-1关联

    Person class{}

    //标识属性

         @Id @Column(name="person_id")

         @GeneratedValue(strategy=GenerationType.IDENTITY)

         private Integer id;

         //定义该Person实体关联的Address实体

         @OneToOne(targetEntity=Address.class)

         //显式使用@JoinTable映射连接表

         @JoinTable(name="person_address",//指定链接表的表名为person_address

         //指定链接表中person_id外键列,参照当前实体对应表的主键列

         joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

         //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列

         inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id")

         )

     

         private Address address;

    2)    有连接表的单项1-1关联

    Person class{}

    //标识属性

         @Id @Column(name="person_id")

         @GeneratedValue(strategy=GenerationType.IDENTITY)

         private Integer id;

         //定义该Person实体关联的Address实体

         @OneToOne(targetEntity=Address.class)

         //显式使用@JoinTable映射连接表

         @JoinTable(name="person_address",//指定链接表的表名为person_address

         //指定链接表中person_id外键列,参照当前实体对应表的主键列

         joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

         //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列

         inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id")

         )

     

         private Address address;

    三、 单项1-N关联

    a)    无连接表的单项1-N关联

    需要在N的一端增加外键列来维护关联关系,可在1的一端使用@JoinColumn修饰Set集合属性、映射外键列即可

    Class person{

    //标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体,没有指定cascade属性

       @OneToMany(targetEntity=Address.class)

       //映射外键列,此处映射的外键列将会添加到关联实体对应的数据表中

       @JoinColumn(name="address_id", refrencedColumnName="address_id",unique=true)

     

       private Set<<Address> address = new HashSet<>();

    }

    b)   有连接表的单项1-N关联

    Class Person{

    //标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

       @OneToMany(targetEntity=Address.class)

       //显式使用@JoinTable映射连接表

       @JoinTable(name="person_address",//指定链接表的表名为person_address

       //指定链接表中person_id外键列,参照当前实体对应表的主键列

       joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

       //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列

       inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true)

       )

     

       private Address address;

    }

    四、单向N-N关联

    单向N-N关联和1—N关联的持久化代码完全相同,控制关系的一端需要增加一个Set类型的属性,被关联的持久化实例以集合形式存在。

           N-N关联需要使用@ManayToMany注解来修饰代表关联实体的集合属性,其属性如下

    属性

    是否必须

    说明

    cascade

    指定Hibernate对关联实体采样怎样的级联策略

    CascadeType.ALL:Hibernate将所有的持久化操作都级联到关联实体

    CascadeType.MERGE:Hibernate将merge操作级联到关联实体

    CascadeType.PERSIST: Hibernate将persist操作级联到关联实体

    CascadeType.REFRESH: Hibernate将refresh操作级联到关联实体

    CascadeType.REMOVE: Hibernate将remove操作级联到关联实体

    fetch

    指定抓取关联实体时的抓取策略,

    FetchType.EAGER:立即抓取关联实体,默认

    FetchType.LAZY: 延迟抓取关联实体。真正用到关联实体才抓取

    mappedBy

    该属性合法的属性值为关联实体的属性名,该属性指定关联实体中哪个属性可引用到当前实体

    targetEntithy

    指定关联实体的类名。默认通过反射来判断关联实体名

    、N-N关联必须使用连接表,与1-N关联相似,都要使用@JoinTable映射,区别是:N-N关联需要去掉@JoinTable中inverseJoinColumns中@JoinColumn的unique=true

    @Entity

     

    @Table(name="person_inf")

    public class Person {

     

       //标识属性

         @Id @Column(name="person_id")

         @GeneratedValue(strategy=GenerationType.IDENTITY)

         private Integer id;

         //定义该Person实体关联的Address实体

         @ManyToMany(targetEntity=Address.class)

         //映射连接表为person_address

         @JoinTable(name="person_address",//指定链接表的表名为person_address

         //定义链接表中名为person_id外键列,参照当前实体对应表的主键列

         joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

         //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列 没有指定unique=true

         inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true)

         )

     

         private Set<Address> address = new HashSet<>();

    }

    五、双向N-N关联

           双向N-N关联需要两端都是用Set集合属性,两端都增加对集合属性的访问。只能使用链接表建立关联

           双向N-N关联需要在两端分别使用@ManyToMany修饰Set集合属性,并在两端都使用@JoinTable显式映射链接表。在两端映射连接表时,两端指定的连接表的表明应该相同,而且两端都使用@JoinTable时指定的外键列的列名也是相互对应的。

           如果希望某一段放弃控制关联关系,则可在这一端的@ManyToMany注解中指定mappedBy属性,这一端就无需、也不能使用@JoinTable映射连接表

           例如:Person和Address都保持双向N-N关联关系

    @Entity

    @Table(name="person_inf")

    public class Person {

     

       //标识属性

         @Id @Column(name="person_id")

         @GeneratedValue(strategy=GenerationType.IDENTITY)

         private Integer id;

         //定义该Person实体关联的Address实体

         @ManyToMany(targetEntity=Address.class)

         //映射连接表为person_address

         @JoinTable(name="person_address",//指定链接表的表名为person_address

         //定义链接表中名为person_id外键列,参照当前实体对应表的主键列

         joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),

         //指定链接表中address_id外键列,参照到当前实体关联实体对应表的主键列 没有指定unique=true

         inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true)

         )

     

         private Set<EAddress> address = new HashSet<>();

    }

    Address实体

    @Entity

    @Table(name="address_inf")

    public class Address {

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

       //定义地址详细信息的成员变量

       private String addressDetail;

       //定义该Address实体所有关联的Person实体

       @ManyToMany(targetEntity=person.class)

       //映射连接表、指定链接表的表名为person_address

       @JoinTable(name="person_address",

       //映射连接表中名为address_id的外键列

       //该列参照当前实体对应表address_id主键列

    joinColumns=@JoinColumn(name="address_id",referencedColumnName="address_id"),

       //映射链接表中名为person_id的外键列

       //该列参照当前实体对应表的person_id主键列

    inverseJoinColumns=@JoinColumn(name="person_id",referencedColumnName="person_id"))

       private Set<Person> persons = new HashSet<>()

    }

    六、双向1-1关联

           双向1-1关联需要修改两端的持久化类代码,让两个持久化类都增加引用关联实体的属性,并为属性提供setter和getter方法

    1.基于外键的双向1-1关联

           对于双向1-1关联,两端都需要使用@OneToOne注解进行映射

           对于基于外键的双向1-1关联,外键可以存放在任意一端。存放外键的一端,需要增加@JoinColumn注解来映射外键列,还应该增加@JoinColumn注解增加unique=true属性来表示该实体实际上是1的一端。

           对于1-1的关联关系,两个实体原本处于平等状态;但选择任意一端增加外键(增加@JoinColumn注解的实体端),该表既变成从表,而另一个表则成为主表。

           对于双向1-1的关联的主表对应的实体,不用于控制关联关系,主表对应的实体中使用@OneToOne注解时,应增加mappedBy属性------该属性表明该实体不管理关联关系,且不能使用@JoinColumn映射外键列

    @Entity

     

    @Table(name="person_inf")

    public class Person {

     

       //标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

    @OneToOne(targetEntity=Address.class,mappedBy="person")

       private Address address2;

    }

    @Entity

    @Table(name="address_inf")

    public class Address {

      

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

       //定义地址详细信息的成员变量

       private String addressDetail;

       //定义该Address实体所有关联的Person实体

       @OneToOne(targetEntity=Person.class)

       //用于映射person_id外键列,参照person_if表的person_id列

       //指定了unique=true表明是1-1关联

    @JoinColumn(name="person_id",referencedColumnName="person_id",unique=true)

       private Person person;

    }

    2.有连接表的双向1-1关联

    有连接表的双向1-1关联需要在两端分别使用@ OneToOne修饰代表关联实体的属性,并在两端都使用@JointTable显式映射连接表。在映射连接表时,两端指定的连接表的表名应该相同,而且两端使用@JoinTable时指定的外键列的列名也是相互对应的。

    需要说明的是,如果程序希望某一端放弃控制关联关系,则可在这一端的@ OneToOne注解中指定mappedBy属性,这一端就无须、也不能使用@JoinColumn映射连接表了。由于此时是1-1关联,因此使用@ JoinTable注解时指定的@ JoinColum都需要增加 unique=true.

    @Entity

     

    @Table(name="person_inf")

    public class Person {

      

    // 标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

       @OneToOne(targetEntity=Address.class)

       //映射底层连接表,表名为person_address

       @JoinTable(name="person_address",//

       //映射链接表的外键列,增加unique=true表明是1-1关联

       joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true),

       //映射链接表的外键列,增加unique=true表明是1-1关联

       inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true)

       )

       private Address address2;

    }

    @Entity

    @Table(name="address_inf")

    public class Address {

      

      

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

       //定义地址详细信息的成员变量

       private String addressDetail;

       //定义该Address实体所有关联的Person实体

       @OneToOne(targetEntity=Person.class)

       //映射底层连接表,表名为person_address 指定了unique=true表明是1-1关联

       @JoinTable(name="person_address",//

       //映射链接表的外键列,增加unique=true表明是1-1关联

       joinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true),

       //映射链接表的外键列,增加unique=true表明是1-1关联

       inverseJoinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id",unique=true))

       private Person person;

    }

    七、双向1-N关联

    对于1-N关联, Hibernate推荐使用双向关联,而且不要让1的一端控制关联关系,而使用N的

    控制关联关系。双向的1-N关联与N-1关联是完全相同的两种情形,两端都需要地加对关联属性的访间,N的一端增加引用到关联实体的属性,1的一端增加集合属性,集合元素为关联实体

    Hibernate同样对这种双向关联映射提供了两种支持:有连接表的和无连接表的,

    1.无连接表的双向1-N关联

           无连接表的双向1-N关联,N的一端需要增加 @Many ToOne注解来修饰代表关联实体的属性,而1的一端则需要使用@ OneToMany注解来修饰代表关联实体的属性关系,实际上只需要在N的底层数据库为了记录这种1-N关联既可,因此应该在使用@ ManyToOne注解的同时,使用@JoinColumn来映射外键。

           前面己经提到,对于双向的1-N关联映射,通常不应该允许1的一端控制关联关系,而应该由N的一端来控制关联关系,因此应该在使用@OneToMany注解时指定 mappedBy属性-------一旦为@OneToMany, @ManyToMany指定了该属性,则表明当前实体不能控制关联关系,当@OneToMany@ManyToMany、@OneToOne所在的当前实体放弃控制关联关系之后, Hibernate就不允许使用@JoinColumn或@ JoinTable修饰代表关联实体的属性了。

           对于指定了 mappedBy属性的@ OneToMany.@ ManyToMamy、@OneToOne注解不能与@ JoinColum或@ JoinTable同时修饰代表关联实体的属性

    @Entity

     

    @Table(name="person_inf")

    public class Person {

      

       标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

       //指定mappedBy属性表明该Person实体不控制关联关系

    @OneToMany(targetEntity=Address.class,mappedBy="person")

       private Set<Address> address = new HashSet<>();

    }

    @Entity

    @Table(name="address_inf")

    public class Address {

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

       //定义地址详细信息的成员变量

       private String addressDetail;

       //定义该Address实体所有关联的Person实体

       @ManyToOne(targetEntity=Person.class)

       //定义名为person_id外键列,参照person_inf表的person_id列

       //指定了unique=true表明是1-1关联

    @JoinColumn(name="person_id",referencedColumnName="person_id",nullable=false)

       private Person person;

    }

    2.有连接的双向1-N关联

    有连接的双向1-N关联,1的一端无需任何改变;只要在N的一端使用@JoinTable显式指定连接表即可。

    @Entity

    @Table(name="address_inf")

    public class Address {

       @Id @Column(name="address_inf")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private int addressId;

       //定义地址详细信息的成员变量

       private String addressDetail;

       //定义该Address实体所有关联的Person实体

       @ManyToOne(targetEntity=Person.class)

       //映射连接表,指定连接表为person_address

    // @JoinTable(name="person_address",//

    // //指定连接表中address_id列参照当前实体对应数据表的address_id主键列

    // joinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true),

    // //指定连接表中person_id列参照当前实体关联实体的对应数据表的person_id主键列

    // inverseJoinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"))

       private Person person;

    }

    @Entity

    @Table(name="person_inf")

    public class Person {

    //标识属性

       @Id @Column(name="person_id")

       @GeneratedValue(strategy=GenerationType.IDENTITY)

       private Integer id;

       //定义该Person实体关联的Address实体

       @OneToMany(targetEntity=Address.class)

       //映射底层连接表,表名为person_address

       @JoinTable(name="person_address",//

       //指定连接表中address_id列参照当前实体对应数据表的person_id主键列

       joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),

       //指定连接表中address_id列参照当前实体关联实体的对应数据表的address_id主键列

       inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id",unique=true)

            )

     

       private Set<Address> address = new HashSet<>();

    }

    对于所有的依赖关系期望先持久化一的一端,再持久化N的一端,或者先持久化被依赖的一端

  • 相关阅读:
    最详细最权威的Android 编码规范
    一款实用的工具手机软件
    一个简单的四则运算程序(优化)
    随笔
    一个简单的四则运算程序
    随手记(四)
    随手记(三)
    随手记(二)
    随手记(一)
    大学生生活中的三大痛点
  • 原文地址:https://www.cnblogs.com/sundaysjava/p/10332387.html
Copyright © 2020-2023  润新知