hibernate注解方式讲解映射关系

Posted 沙漠皇帝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate注解方式讲解映射关系相关的知识,希望对你有一定的参考价值。

          注解方式讲解映射关系

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注解方式讲解映射关系的主要内容,如果未能解决你的问题,请参考以下文章

《Java从入门到放弃》入门篇:使用注解的方式配置hibernate映射关系

《Java从入门到放弃》入门篇:使用注解的方式配置hibernate映射关系

Hibernate4学习总结

hibernate annotation注解方式来处理映射关系

hibernate annotation注解方式来处理映射关系

hibernate关联映射注解