Jpa-多表关联-OneToOne

5 篇文章 0 订阅


OneToOnehibernate中用于对表与表之间进行维护关联

准备


import com.alibaba.fastjson.JSON;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "t_user_account", schema = "test")
public class TUserAccount {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "msg", length = 50)
    private String msg;

    @JoinColumn(name = "user_account", referencedColumnName = "id")
    @OneToOne
    private TUser user;

    public String toString() {
        return JSON.toJSONString(this);
    }
}
@Entity
@Table(name = "t_user", schema = "test")
@Data
public class TUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "real_name", length = 50)
    private String realName;

    //.....

}
-- auto-generated definition
create table t_user
(
    id          bigint auto_increment
        primary key,
    real_name   varchar(50)                        null comment '实际名称',
    age         bigint                             null,
    sex         varchar(255)                       null,
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    is_delete   tinyint  default 0                 not null comment '是否删除'
)
    comment '用户表';

-- auto-generated definition
create table t_user_account
(
    id           bigint auto_increment
        primary key,
    user_account bigint      null,
    msg          varchar(50) null
);

JoinColumn

OneToOne一起使用的情况下。
JoinColumn用于定义外键关系。
name:用当前表那个字段作为目标表的外键,默认是实体名_字段名
referencedColumnName:与源表用那个字段进行,默认为当前表的主键

OneToOne属性

targetEntity

关联的目标实体类。默认为存储关联的字段的类型。

cascade*

表明那些操作需要级联操作。默认为空。但是查询的时候是会进行级联查询的。

PERSIST

只有插入(INSERT)操作时进行级联操作 插入主表的同时会插入子表。image.png
当插入操作时,如果没有标注当前PERSIST方法时则会报错。
image.png

// 修改TUserAccount.java中的 @OneToOne(cascade = {CascadeType.PERSIST})

@Test
public void testOneToOneInsert(){
    TUserAccount entity = new TUserAccount();
    entity.setMsg("INSERT");
    TUser user = new TUser();
    user.setRealName("INSERT");
    entity.setUser(user);
    // 对主表进行INSERT操作
    userAccountRepository.save(entity);
}
MERGE

只有更新(UPDATE)操作时进行级联操作,更新时如果将关联属性修改为null会把当前表的关联的字段改为null。默认是不会删除关联表的行数据( 注意这里不会将关联表的行数据给删除,需要删除的话则需要开启orphanRemoval)。

// 修改TUserAccount.java中的 @OneToOne(cascade = {CascadeType.MERGE})

@Test
public void testOneToOneUpdate(){
    TUserAccount newEntity = new TUserAccount();
    newEntity.setId(11L);
    newEntity.setMsg("MERGE");
    newEntity.setUser(null);
    userAccountRepository.save(newEntity);
}

image.png
image.png

进行级联查询后,只对当前表进行update操作,将user_account字段置为null

REMOVE

只有删除(DELETE)操作时进行级联操作,删除主表的同时会把子表也删除

// 修改TUserAccount.java中的 @OneToOne(cascade = {CascadeType.REMOVE})

@Test
public void testOneToOneDelete(){
    userAccountRepository.deleteById(15L);
}

image.png

级联查询后,对主表进行删除,再后关联表进行删除。

REFRESH

EntityManager.refresh() 方法用于重新加载实体的状态,从数据库中获取最新的数据,并覆盖当前持久化上下文中的实体状态

orphanRemoval

当进行更新操作时,将关联属性修改为null,会删除关联的子表数据。默认为false

// 修改TUserAccount.java中的 @OneToOne(cascade = {CascadeType.MERGE},orphanRemoval=true)

@Test
public void testOneToOneOrphanRemoval(){
    TUserAccount newEntity = new TUserAccount();
    newEntity.setId(11L);
    newEntity.setMsg("MERGE");
    newEntity.setUser(null);
    userAccountRepository.save(newEntity);
}

image.png

级联查询后,对主表进行更新,将user_account改为null,并删除t_user的记录。

fetch

  • EAGER:立即获取数据(默认)与主表一起查出
  • LAZY:如果是LAZY则是当我们使用关联表对象的时候才会去进行查询。注意使用LAZY时需要@Transactional中进行使用,因为如果查询完session关闭了就不能从里面获取数据了。
// 修改TUserAccount.java中的 @OneToOne(cascade = {CascadeType.ALL},orphanRemoval=true,fetch = FetchType.LAZY)

@Test
@Transactional
public void testOneToOneFetchLazy(){
    TUserAccount tUserAccount = userAccountRepository.findById(6L).get();
    System.out.println("================wait================");
    System.out.println(tUserAccount.getUser());
}

image.png

先只查主表,如果我们没有使用则不会对关联表进行查询,而到我们获取关联表信息的时候再去对关联表进行查询,

optional

是否允许为空,默认是true。为false时不能将关联字段设置为null。表示为非空的关联关系。

MappedBy*

表示关联关系为当前字段类型的的实体来进行维护,指定的值为目标类型中的外键字段。这里删除,更新,不会对关联进行操作。

// 在TUser中添加 
@OneToOne(mappedBy = "user") 
private TUserAccount userAccount;
// 
@Test
public void testQueryMappedBy(){
    TUser tUser = userRepository.findById(7017L).get();
    System.out.println(tUser);
    tUser.setUserAccount(null);
    userRepository.save(tUser);
}

image.png

当查询t_user的时候也可以把t_user_account查询出来。对t_user的uesrAccount进行操作的时候不会对数据库中的字段进行影响

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

假女吖☌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值