在哪种情况下,您使用JPA@JoinTable批注?

推荐答案

EDIT 2017-04-29:正如一些 comments 者指出的那样,JoinTable示例不需要mappedBy注释属性.事实上,最新版本的Hibernate通过打印以下错误来拒绝启动:

org.hibernate.AnnotationException: 
   Associations marked as mappedBy must not define database mappings 
   like @JoinTable or @JoinColumn

让我们假设您有一个名为Project的实体和另一个名为Task的实体,并且每个项目都可以有多个任务.

您可以通过两种方式为这个场景设计数据库模式.

第一种解决方案是创建一个名为Project的表和另一个名为Task的表,并向名为project_id的任务表中添加一个外键列:

Project      Task
-------      ----
id           id
name         name
             project_id

这样,就可以为任务表中的每一行确定项目.如果使用这种方法,在实体类中就不需要联接表:

@Entity
public class Project {

   @OneToMany(mappedBy = "project")
   private Collection<Task> tasks;

}

@Entity
public class Task {

   @ManyToOne
   private Project project;

}

另一种解决方案是使用第三个表,例如Project_Tasks,并将项目和任务之间的关系存储在该表中:

Project      Task      Project_Tasks
-------      ----      -------------
id           id        project_id
name         name      task_id

Project_Tasks表被称为"联接表".要在JPA中实现第二个解决方案,需要使用@JoinTable注释.例如,为了实现单向一对多关联,我们可以将实体定义为:

100 entity:

@Entity
public class Project {

    @Id
    @GeneratedValue
    private Long pid;

    private String name;

    @JoinTable
    @OneToMany
    private List<Task> tasks;

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

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

    public List<Task> getTasks() {
        return tasks;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }
}

100 entity:

@Entity
public class Task {

    @Id
    @GeneratedValue
    private Long tid;

    private String name;

    public Long getTid() {
        return tid;
    }

    public void setTid(Long tid) {
        this.tid = tid;
    }

    public String getName() {
        return name;
    }

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

}

这将创建以下数据库 struct :

ER Diagram 1

@JoinTable注释还允许您自定义联接表的各个方面.例如,如果我们对tasks属性进行如下注释:

@JoinTable(
        name = "MY_JT",
        joinColumns = @JoinColumn(
                name = "PROJ_ID",
                referencedColumnName = "PID"
        ),
        inverseJoinColumns = @JoinColumn(
                name = "TASK_ID",
                referencedColumnName = "TID"
        )
)
@OneToMany
private List<Task> tasks;

生成的数据库将变成:

ER Diagram 2

最后,如果要为多对多关联创建模式,使用联接表是唯一可用的解决方案.

Java相关问答推荐

Java SSLocket查明客户端是否发送了证书

编译期间错误(Java 0000)Android .Net MAUI

在URL类图中表示Java swing类

Java中不同包中的类之间的配置共享

Java 8中的多个字段和计数

Jlink选项&-strie-ative-Commands";的作用是什么?

第二次按下按钮后,我需要将按钮恢复到其原始状态,以便它可以再次工作

由于 list 中的权限错误,Android未生成

无法在Java中处理PayPal支付响应

未找到适用于响应类型[类java.io.InputStream]和内容类型[Text/CSV]的HttpMessageConverter

声明MessageChannel Bean的首选方式

在学习Spring时,通过构造函数参数0表达了不满意的依赖关系

当构造函数创建一个新实例时,Java为什么需要&new";

Dijkstra搜索算法的实现

从LineChart<;字符串、字符串和gt;中删除数据时出现特殊的ClassCastException;

插入中的JOOQ序列,设置为VS值

在Java中将.GRF转换为图像文件

H2数据库仅支持%1个结果集?

ControlsFX RangeSlider在方向垂直时滞后

Java中计算大n和k值模10^9+7的二项式系数的乘法公式输出错误值