hibernate关联映射注解

来源:互联网 发布:cf刷军衔软件 编辑:程序博客网 时间:2024/05/17 02:49

hibernate的关联映射

无连接表的N-1关联

使用@JoinColumn来修饰代表关联实体的属性。映射底层的外键列。
person->Address(n-1)

@Entity@Table(name="person_inf")public class Person{ ....  @ManyToOne(targetEntity=Address.class)  @JoinColumn(name="address_id" , nullable=false)  @Cascade(CascadeType.ALL)  private Address address;

有连接表的N-1关联

使用@JoinTable映射底层连接表的 信息

@ManyToOne(targetEntity=Address.class)  @JoinTable(name="person_address",     joinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id", unique=true),    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id")  )  private Address address;

单向1-1

使用@OnetoOne and @JoinColumn并指定unique=true

@OneToOne(targetEntity=Address.class)  @JoinColumn(name="address_id"    , referencedColumnName="address_id" , unique=true)  private Address address;

有连接表的单向1-1

这种情况很少见,但是hibernate还是提供了支持。只要在相应的@inverseJoinColumn属性映射的外键列增加unique=true即可

@OneToOne(targetEntity=Address.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id" , unique=true),    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id", unique=true)  )  private Address address;

无连接表的单向1-N关联

在1的一端使用JoinColumn修饰集合Set属性,映射外键列即可。

@OneToMany(targetEntity=Address.class)  @JoinColumn(name="person_id" , referencedColumnName="person_id")  private Set<Address> addresses    = new HashSet<>();

有连接表的单向1-N

@OneToMany(targetEntity=Address.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id"),    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id", unique=true)  )  private Set<Address> addresses    = new HashSet<>();

单向的N-N

使用@ManyToMany @JoinTable来映射连接表。并且去掉@inverseJoinColumns属性所指定的@JoinColumn中的unique=true

@ManyToMany(targetEntity=Address.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id"),    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id")  )  private Set<Address> addresses    = new HashSet<>();

双向1-N关联

推荐使用双向1-N关联。并且让N的一端控制关联关系。
无连接表的双向1-n关联。
N的一端:@OneToMany(mappedBy=”“)
1的一端:@ManyToOne @JoinColumn来映射外键列。

@Entity@Table(name="person_inf")public class Person{....  @OneToMany(targetEntity=Address.class    , mappedBy="person")  private Set<Address> addresses    = new HashSet<>();} @Entity@Table(name="address_inf")public class Address{  ...  @ManyToOne(targetEntity=Person.class)  @JoinColumn(name="person_id" , referencedColumnName="person_id"    , nullable=false)  private Person person;}

有连接表的双向1-N关联
1的一端无需改变
N的一端@JoinTable指定连接表

 @OneToMany(targetEntity=Address.class    , mappedBy="person")  private Set<Address> addresses    = new HashSet<>();@ManyToOne(targetEntity=Person.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id", unique=true),    inverseJoinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id")  )  private Person person;}

双向N-N关联

双方都是用@ManyToMany @JoinTable属性

  @ManyToMany(targetEntity=Person.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="address_id"    inverseJoinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id")  )  private Set<Person> persons    = new HashSet<>();@ManyToMany(targetEntity=Address.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="person_id"    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id")  )  private Set<Address> addresses    = new HashSet<>();

双向1-1关联

  1. 基于外键
@OneToOne(targetEntity=Address.class , mappedBy="person")  private Address address;@OneToOne(targetEntity=Person.class)  @JoinColumn(name="person_id" , referencedColumnName="person_id"    , unique=true)  private Person person;
  1. 有连接表
    不推荐使用
  @OneToOne(targetEntity=Address.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id" , unique=true),    inverseJoinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id", unique=true)  )  private Address address;    @OneToOne(targetEntity=Person.class)  @JoinTable(name="person_address",    joinColumns=@JoinColumn(name="address_id"      , referencedColumnName="address_id", unique=true),    inverseJoinColumns=@JoinColumn(name="person_id"      , referencedColumnName="person_id" , unique=true)  )  private Person person;

组件属性包含的关联实体

PersonL里面包含组件Address,Address跟School是1-N的关系。

@Entity@Table(name="person_inf")public class Person{  @Id @Column(name="person_id")  @GeneratedValue(strategy=GenerationType.IDENTITY)  private Integer id;  private Address address;}@Embeddablepublic class Address{  @Column(name="address_detail")  private String addressDetail;  @Parent  private Person person;  @OneToMany(targetEntity=School.class)  @JoinColumn(name="address_id", referencedColumnName="person_id")  private Set<School> schools    = new HashSet<>();}@Entity@Table(name="school_inf")public class School{ @Id @Column(name="school_id")  @GeneratedValue(strategy=GenerationType.IDENTITY)  private Integer id;

基于复合主键的关联关系

不推荐使用。总是建议使用没有物理意义的逻辑主键。
对于1-N的双向关联,1的一端将两个属性结合起来作为复合主键。N的一端仍然使用Integer类型的普通主键。
person(1)->address(n)

  @Id  private String first;  @Id  private String last;  @OneToMany(targetEntity=Address.class, mappedBy="person"    , cascade=CascadeType.ALL)  private Set<Address> addresses    = new HashSet<>();public class Address{@ManyToOne(targetEntity=Person.class)  @JoinColumns({    @JoinColumn(name="person_first"      , referencedColumnName="first" , nullable=false),    @JoinColumn(name="person_last"      , referencedColumnName="last" , nullable=false)  })  private Person person;  }

hibernate的继承映射

例子:现在有四个类:Person,Employee,Manager,Customer.四个持久化类,其中person还有一个Address组件。
person派生出了employee和customer,employee又派生出了manager.
1. 整个类层次对应一个表(默认)
所有类的属性都放在一个表中。并使用一个列来辨别一条记录到底是属于哪个类的实例。俗称辨别者列(discriminator)。

@Entity@DiscriminatorColumn(name="person_type" ,  discriminatorType=DiscriminatorType.STRING)@DiscriminatorValue("普通人")@Table(name="person_inf")public class Person{  @Id @Column(name="person_id")  @GeneratedValue(strategy=GenerationType.IDENTITY)  private Integer id;  private String name;  private char gender;  @AttributeOverrides({    @AttributeOverride(name="detail",    column=@Column(name="address_detail")),    @AttributeOverride(name="zip",    column=@Column(name="address_zip")),    @AttributeOverride(name="country",    column=@Column(name="address_country"))  })  private Address address;  }  @Entity@DiscriminatorValue("员工")@Table(name="employee_inf")public class Employee extends Person{  private String title;  private double salary;  @OneToMany(cascade=CascadeType.ALL    , mappedBy="employee" , targetEntity=Customer.class)  private Set<Customer> customers    = new HashSet<Customer>();  @ManyToOne(cascade=CascadeType.ALL    ,targetEntity=Manager.class)  @JoinColumn(name="manager_id", nullable=true)  private Manager manager;  }@Entity@DiscriminatorValue("经理")@Table(name="manager_inf")public class  Manager extends Employee{  private String department;  @OneToMany(cascade=CascadeType.ALL    , mappedBy="manager" , targetEntity=Employee.class)  private Set<Employee> employees    = new HashSet<Employee>();

2.连接子类的映射策略
父类保存在父类表中,子类由父类表和子类表共同保存。
在继承树的根类中,使用@Inheritance指定映射策略。
@InheritanceType.SINGLE_TABLE:整个类层次一个表
@InheritanceType.JOINED:连接子类
@InheritanceType.TABLE_PER_CLASS:每个类对应一个表。
这种策略无需指定辨别者列。

@Entity@Inheritance(strategy=InheritanceType.JOINED)@Table(name="person_inf")public class Person{  // ±êʶÊôÐÔ  @Id @Column(name="person_id")  @GeneratedValue(strategy=GenerationType.IDENTITY)  private Integer id;  } @Entity@Table(name="employee_inf")public class Employee extends Person{  private String title;  private double salary;  @OneToMany(cascade=CascadeType.ALL    , mappedBy="employee" , targetEntity=Customer.class)  private Set<Customer> customers    = new HashSet<>();  @ManyToOne(cascade=CascadeType.ALL    ,targetEntity=Manager.class)  @JoinColumn(name="manager_id", nullable=true)  private Manager manager;  }

3.每个类一个表
不能使用@GenerationType.IDENTIFIED,@GenerationType.AUTO指定主键生成策略。

@Entity@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)@Table(name="person_inf")public class Person{  @Id @Column(name="person_id")  @GenericGenerator(name="person_hilo" , strategy="hilo")  @GeneratedValue(generator="person_hilo")  private Integer id;  }@Entity@Table(name="employee_inf")public class Employee extends Person{  private String title;  private double salary;  @OneToMany(cascade=CascadeType.ALL    , mappedBy="employee" , targetEntity=Customer.class)  private Set<Customer> customers    = new HashSet<>();
0 0
原创粉丝点击