1. 程式人生 > >hibernate 註解方式講解映射關系

hibernate 註解方式講解映射關系

在外 entity 方便 log 建設 中間 建表 遺憾 存在

註解方式講解映射關系

1 One-To-One Unidirectional with Foreign Key

單向關聯外鍵方式。

1.1 關系如下

技術分享圖片

學生和地址關系的例子。一個學生住在一個地址上。一個地址只能由一個學生占用。

1.2 Address代碼:

package com.daodaofun.domain;

import javax.persistence.*;

@Entity
@Table(name="STUDENT")
public class Student {

    @Id
    @GeneratedValue
    @Column(name
="STUDENT_ID") private Long id; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; @OneToOne @JoinColumn(name = "ADDRESS_ID") private Address address; public Student() { } public Long getId() {
return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }

這樣可以不用寫hbm.xml,還是挺方便的。此時註意在Student一端配置了JoinColumn,也就是關聯的列,那麽就會在Student表當中添加home_address_id這一列,作為外鍵。

外鍵名稱如果需要指定可以使用@Foreignkey,遺憾的是這個版本已經是過時了,JPA的註解沒有過時,但是無法加在這個屬性之上,所以要麽使用過時的註解,要麽你忍受,或者你自行建表。

2 One-To-One Bidirectianal

所謂的雙向配置也差不了多少,就是在另外一端一樣加上引用即可,即在Address這一段一樣持有Student。並且加上如下註解即可:


@OneToOne
private Student student;

但是這樣有個問題,會導致雙外鍵,這個明顯屬於冗余,這個時候我們需要指明誰來主導,外鍵由誰來建設的問題,所以我們需要額外設置一下如下:

@OneToOne(mappedBy = "address")
private Student student;

這樣就比較合理了。

3 Many-To-One Bidirectional

多對一雙向

我們以學生與大學的關系為例,一所大學可以有很多學生。

關系圖如下:

技術分享圖片

3.1 University代碼:

-··在一的一方配置OneToMany,同樣的由於我們會將外鍵設置在多的一方,所以要將這個建設權交給對方,所以要加上mappedBy。

package com.daodaofun.domain;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="UNIVERSITY")
public class University {

    @Id
    @GeneratedValue
    @Column(name="UNIVERSITY_ID")
    private Long id;

    @Column(name="NAME")
    private String name;

    @Column(name="COUNTRY")
    private String country;

    @OneToMany(mappedBy = "university",cascade = CascadeType.ALL)
    private List<Student> students;


    public University() {
    }


    public University(String name, String country) {
        this.name = name;
        this.country = country;
    }


    public Long getId() {
        return id;
    }


    public void setId(Long id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public String getCountry() {
        return country;
    }


    public void setCountry(String country) {
        this.country = country;
    }


    public List<Student> getStudents() {
        return students;
    }


    public void setStudents(List<Student> students) {
        this.students = students;
    }




}

3.2 Student代碼:

package com.daodaofun.domain;

import javax.persistence.*;

@Entity
@Table(name="STUDENT")
public class Student {

    @Id
    @GeneratedValue
    @Column(name="STUDENT_ID")
    private Long id;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "LAST_NAME")
    private String lastName;


    @ManyToOne(optional = false)
    @JoinColumn(name = "UNIVERSITY_ID")
    private University university;

    public Student() {
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public University getUniversity() {
        return university;
    }

    public void setUniversity(University university) {
        this.university = university;
    }
}

在多的一方,同樣的指明建設外鍵是什麽列加上JoinColumn,此外這裏有一個optional=false,這個是什麽含義呢?

(Optional) Whether the association is optional. If set

to false then a non-null relationship must always exist.

關聯關系是否可選,如果設置為了false,那麽就必須為非空關系。

4 Many-To-Many Bidirectional

雙向多對多

在多對多關聯中,使用了一個額外的表(稱為聯接表),其主鍵是兩個關聯表的主鍵的組合。換句話說,聯接表和關聯表之間存在外鍵關聯表。

討論一個學生和學科關系的例子。一名學生可以註冊多個科目。一個科目可以有多個學生註冊。

關系圖如下:

技術分享圖片

向這種多多關系其實都是通過一張中間表來體現的。

4.1 Student代碼:

package com.daodaofun.domain;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="STUDENT")
public class Student {

    @Id
    @GeneratedValue
    @Column(name="STUDENT_ID")
    private Long id;

    @Column(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "LAST_NAME")
    private String lastName;


    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "STUDENT_SUBJECT",joinColumns = {@JoinColumn(name = "STUDENT_ID")},
                inverseJoinColumns = {@JoinColumn(name = "SUBJECT_ID")})
    private List<Subject> subjects = new ArrayList<>();

    public Student() {
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }


    public List<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<Subject> subjects) {
        this.subjects = subjects;
    }
}

4.2 subject代碼:

package com.daodaofun.domain;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "SUBJECT")
public class Subject {


    @Id
    @GeneratedValue
    @Column(name = "SUBJECT_ID")
    private Long id;

    @Column(name = "name")
    private String name;

    @ManyToMany(mappedBy = "subjects")
    private List<Student> students = new ArrayList<>();


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
} 

這裏可以指定任意一方來負責設置表的生成方式,此處是由subjects來設置,需要註意的是

@JoinTable(name = "STUDENT_SUBJECT",joinColumns = {@JoinColumn(name = "STUDENT_ID")},
                inverseJoinColumns = {@JoinColumn(name = "SUBJECT_ID")})通過name指定了中間表名稱,然後指明需要生成的列,兩列就是student表和subject表各自的主鍵。


以上幾種是比較實用的映射關系方式,hibernate可以配置映射的方式特別多,上面幾種差不多夠用了。

hibernate 註解方式講解映射關系