JPA中实现双向一对一的关联关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA中实现双向一对一的关联关系相关的知识,希望对你有一定的参考价值。


场景

按照上面的流程实现以上映射关系后,怎样在JPA中实现双向一对一的映射关系。

比如部门与经理就是双向一对一的关系。

注:

关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

为了构造出双向一对一的关联关系,新增经理和部门两个数据库表和实体类。

新建数据库表JPA_MANAGERS经理表

JPA中实现双向一对一的关联关系_java

 

设计部门表JPA_DEPARTMENTS

JPA中实现双向一对一的关联关系_java_02

 

然后新建部门实体类Department

package com.badao.jpa.helloworld;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Table(name="JPA_DEPARTMENTS")
@Entity
public class Department

private Integer id;
private String deptName;

private Manager mgr;

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
public Integer getId()
return id;


public void setId(Integer id)
this.id = id;


@Column(name="DEPT_NAME")
public String getDeptName()
return deptName;


public void setDeptName(String deptName)
this.deptName = deptName;


//使用 @OneToOne 来映射 1-1 关联关系。
//若需要在当前数据表中添加主键则需要使用 @JoinColumn 来进行映射. 注意, 1-1 关联关系, 所以需要添加 unique=true
@JoinColumn(name="MGR_ID", unique=true)
@OneToOne(fetch=FetchType.LAZY)
public Manager getMgr()
return mgr;


public void setMgr(Manager mgr)
this.mgr = mgr;

注:

1.使用 @OneToOne 来映射 1-1 关联关系。

2.若需要在当前数据表中添加主键则需要使用 @JoinColumn 来进行映射. 注意, 1-1 关联关系, 所以需要添加 unique=true。

3.这里是双向的一对一映射,所以要选择一方作为维护主要关联关系的一方添加@JoinColumn(name="MGR_ID", unique=true)

然后再新建经理实体类

package com.badao.jpa.helloworld;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Table(name="JPA_MANAGERS")
@Entity
public class Manager

private Integer id;
private String mgrName;

private Department dept;

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
public Integer getId()
return id;


public void setId(Integer id)
this.id = id;


@Column(name="MGR_NAME")
public String getMgrName()
return mgrName;


public void setMgrName(String mgrName)
this.mgrName = mgrName;


//对于不维护关联关系, 没有外键的一方, 使用 @OneToOne 来进行映射, 建议设置 mappedBy=另一方外键
@OneToOne(mappedBy="mgr")
public Department getDept()
return dept;


public void setDept(Department dept)
this.dept = dept;

注:

1.对于不维护关联关系, 没有外键的一方, 使用 @OneToOne 来进行映射, 建议设置 mappedBy=另一方外键。

2.因为此方不维护关联关系,所以直接使用@OneToOne的mappedBy属性,属性值对应的是另一方的外键属性名。

然后在配置文件persistence.xml中添加实体类的配置

<class>com.badao.jpa.helloworld.Manager</class>
<class>com.badao.jpa.helloworld.Department</class>

添加位置如下

JPA中实现双向一对一的关联关系_JPA_03

 

然后编写单元测试方法

 

@Test
public void testOneToOnePersistence()
Manager mgr = new Manager();
mgr.setMgrName("M-BB");

Department dept = new Department();
dept.setDeptName("D-BB");

//设置关联关系
mgr.setDept(dept);
dept.setMgr(mgr);

//执行保存操作
entityManager.persist(mgr);
entityManager.persist(dept);

注:

双向 1-1 的关联关系, 建议先保存不维护关联关系的一方, 即没有外键的一方, 这样不会多出 UPDATE 语句。

运行单元测试方法后查看数据库表

经理表

JPA中实现双向一对一的关联关系_java_04

 

部门表

JPA中实现双向一对一的关联关系_java_05

 

JPA映射关系

关系:

实体关系是指实体与实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。

一对一两种配置方式:

  1:主键共享(把一个实体的主键配置为另外一个实体的主键)

  2:配合唯一外键

技术图片

 

单项一对多

  :配置一个实体的外键     数据库外键存在多方,最好让多方来维护外键 ,一方放弃管理维护

技术图片

 

双向多对一/双向一对多

 

public class ProductDir

 

  @Id

 

  @GeneratedValue

 

  private Long id;

 

  private String name;

 

  @OneToMany

 

  @JoinColumn(name="dir_id")

 

  private Set<Product> products = new HashSet<Product>();

 

  

 

@Entity

 

public class Product

 

  @Id

 

  @GeneratedValue

 

  private Long id;

 

  private String name;

 

  @ManyToOne(fetch = FetchType.LAZY) // 实现延迟加载

 

  @JoinColumn(name = "dir_id")

 

  private ProductDir dir;

集合映射的类型

  1.list     PersistentBag(有序,可以重复

     2.set     PersistentSet(无序,不可以重复

 

级联

    :

    级联保存  PERSIST

    级联删除  REMOVE

    全部    ALL

    孤儿删除 orphanRemoval = true (从一方解除关系,让多方外键置为空)

 

单项多对多

    

  @ManyToMany

       @joinTable 中间表配置

  joinColumns:首 个列名   inverseJoinColumns: 下个列名

    实体类没什么变化   默认懒加载  只配置一个实体类

双向多对多

      列Teacher/Student

技术图片

 

 技术图片

 

 

 

 

 

 

 

 

 

 

 

以上是关于JPA中实现双向一对一的关联关系的主要内容,如果未能解决你的问题,请参考以下文章

JPA映射关系

JPA 一对多双向堆栈溢出问题

Spring Data JPA中的mappedBy

JPA双向一对多多一对一

JPA:映射关联关系------映射单向多对一的关联关系

jpa休眠一对多双向[重复]