如何使用JPA注解标注一对一的关系

假设应用场景如下:Node与PageServer是一对一的关系,其中,Node类对应node表如下:

CREATE TABLE `node` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;


PageServer类对应page_server表如下:

CREATE TABLE `pageserver` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`node_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_reference_67` FOREIGN KEY (`node_id`) REFERENCES `node` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;



两个类分别如下:


public class Node {
private PageServer pageServer;//PageServer实体

@OneToOne(mappedBy = "node", fetch = FetchType.LAZY)
public PageServer getPageServer() {
return pageServer;
}

public void setPageServer(PageServer pageServer) {
this.pageServer = pageServer;
}

}


说明

1、该类经过简化,没有全部列出代码,在此我们只关注OneToOne注解及其属性设置。

2、@OneToOne

@OneToOne注解指明 Node 与 PageServer 为一对一关系,@OneToOne注解有五个属性:mappedBy、fetch、targetEntity、cascade 和 optional 。

3、mappedBy=”node”

如果两个实体Bean是双向一对一关联关系,那么使用了mappedBy的一端我们称为关系目标方(方便起见,称为被控方他the Owned),另一端称之为关系拥有方(方便起见,称为控制方 the Owner)。相应的对象称之为被控对象和主控对象。

只有在双向关联时才会使用mappedBy属性,只有OneToOne、OneToMany、ManyToMany上才有mappedBy属性,ManyToOne不存在该属性。

mappedBy标签一定是定义在the owned side(被拥有方的),并指向the owning side(拥有方)的。在本例中,Node类为关系目标方,即被控对象,the Owned 端;PageServer类为关系拥有方,即主控对象, the Owner 。

mappedBy跟JoinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方中有被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。

4、fetch = FetchType.LAZY

FetchType类型的属性。可选择项包括:FetchType.EAGER 和FetchType.LAZY。

fetch属性默认值是FetchType.EAGER。

FetchType.EAGER表示被控对象(本例是Node类)在主控对象加载的时候同时加载,FetchType.LAZY表示被控对象在被访问时才加载。默认值是FetchType.LAZY。

5、targetEntity

Class类型的属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。


public class PageServer {
private Node node;//所属节点

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "node_id")
@Fetch(FetchMode.JOIN)
public Node getNode() {
return this.node;
}

public void setNode(Node node) {
this.node = node;
}
}


说明

[b]1、cascade属性[/b]

该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作, 而且这种关系是递归调用的。

默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括:

[b]CascadeType.ALL[/b]
针对拥有实体执行的任何持续性操作均层叠到关联的目标。

[b]CascadeType.MERGE[/b]
如果合并了拥有实体,则将 merge 层叠到关联的目标。

[b]CascadeType.PERSIST[/b]
如果持久保存拥有实体,则将 persist 层叠到关联的目标。

[b]CascadeType.REFRESH[/b]
如果刷新了拥有实体,则 refresh 为关联的层叠目标。

[b]CascadeType.REMOVE[/b]
如果删除了拥有实体,则还删除关联的目标。

[b]2、JoinColumn属性[/b]

@OneToOne注释只能确定实体与实体的关系是一对一的关系,不能指定数据库表中的保存的关联字段。所以此时要结合@JoinColumn标记来指定保存实体关系的配置。

[b]3、Fetch属性[/b]

可设置以下三个值:
@Fetch(FetchMode.JOIN) 会使用left join查询,只产生一条sql语句;
@Fetch(FetchMode.SELECT) 会产生N+1条sql语句;
@Fetch(FetchMode.SUBSELECT) 产生两条sql语句 第二条语句使用id in (…..)查询出所有关联的数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联互通社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值