gpt4 book ai didi

java - 如何与 Spring Data JDBC 建立一对一关系模型?

转载 作者:行者123 更新时间:2023-11-29 14:29:40 25 4
gpt4 key购买 nike

我想使用 Spring Data JDBC 和 PostgreSQL 为一对一关系建模,但我无法以正确的方式设置根聚合。

有以下场景:Picture , SQL
每个引擎都是唯一的,car 有唯一的列 engine_idengine.id 的外键,同样适用于 truck。因此 car 和 truck 应该是根聚合,所以当 car 或 truck 被删除时,引擎表中引用的行也应该被删除。

根据我对Spring Data JDBC Aggregates的理解

If multiple aggregates reference the same entity, that entity can’t be part of those aggregates referencing it since it only can be part of exactly one aggregate.

所以问题是:

  • 由于上面的解释,是否有可能的解决方法,以便通过对 cartruck 执行 CRUD 操作,更改也会反射(reflect)到 engine 中?
  • 使用 Spring Data JDBC 在 Java 中实现这种关系的最佳方法是什么?

这是我的看法,虽然行不通,但应该可以阐明我要完成的目标。

汽车.java

package com.example.dao.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

import java.util.UUID;

@Table("car")
public class Car implements Persistable<UUID> {

@Id
private UUID id;

String brand;

String model;

@Column("engine_id")
Engine engine;

public void setId(UUID id) {
this.id = id;
}

@Override
public UUID getId() {
return id;
}

@Override
public boolean isNew() {
return id == null;
}
}

引擎.java

package com.example.dao.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Table;

import java.time.LocalDateTime;
import java.util.UUID;

@Table("engine")
public class Engine implements Persistable<UUID> {

@Id
private UUID id;

String name;

LocalDateTime dateCreated;

String type;

public void setId(UUID id) {
this.id = id;
}

@Override
public UUID getId() {
return id;
}

@Override
public boolean isNew() {
return id == null;
}
}

卡车.java

package com.example.dao.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

import java.util.UUID;

@Table("truck")
public class Truck implements Persistable<UUID> {

@Id
private UUID id;

String brand;

String model;

Integer cargoMaxWeight;

String truckType;

@Column("engine_id")
Engine engine;

public void setId(UUID id) {
this.id = id;
}

@Override
public UUID getId() {
return id;
}

@Override
public boolean isNew() {
return id == null;
}
}

最佳答案

我看到有四个选项可以在 Java 中对其进行建模。请注意,其中大多数需要调整您的数据库架构。

一般的问题是 Spring Data JDBC 假定引用的实体 (Engine) 在其表中有一列引用拥有实体 (Car/车辆)。这有一个问题:https://jira.spring.io/browse/DATAJDBC-128从这里开始,您有以下选择:

  1. 将列添加到引擎表中,生成如下所示的实体和模式(所有实体都减少到与问题相关的最小值):

    public class Car {

    @Id
    Long id;
    String name;

    Engine engine;
    }

    public class Truck {

    @Id
    Long id;
    String name;

    Engine engine;
    }

    public class Engine {

    String name;
    }

    CREATE TABLE CAR (
    id BIGINT IDENTITY,
    NAME VARCHAR(200)
    );

    CREATE TABLE TRUCK (
    ID BIGINT IDENTITY,
    NAME VARCHAR(200)
    );

    CREATE TABLE ENGINE (
    TRUCK BIGINT,
    CAR BIGINT,
    NAME VARCHAR(200),
    FOREIGN KEY (TRUCK) REFERENCES TRUCK (ID),
    FOREIGN KEY (CAR) REFERENCES CAR (ID)
    );

    我在 GitHub 上提供了一个完整的示例:https://github.com/schauder/so-sd-jdbc-multipleonetoone .

  2. 如果您不喜欢这两个列,您可以修改映射以对两个引用使用相同的列。但是你必须确保 CarVehicle 的 id 是不同的。即使那样,这种方法也存在一个大问题:

    Car 存储库或 Truck 车辆上的

    deleteAll删除所有引擎!!!因此不推荐这种方法!

    如果您仍想使用它,这里是架构和实体的代码。

    public class Car {

    @Id
    Long id;
    String name;

    @Column(value = "vehicle")
    Engine engine;
    }

    public class Truck {

    @Id
    Long id;
    String name;

    @Column(value = "vehicle")
    Engine engine;
    }

    public class Engine {

    String name;
    }


    CREATE TABLE CAR (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY ,
    NAME VARCHAR(200)
    );

    CREATE TABLE TRUCK (
    ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH -1, INCREMENT BY -1) PRIMARY KEY ,
    NAME VARCHAR(200)
    );

    CREATE TABLE ENGINE (
    VEHICLE BIGINT,
    NAME VARCHAR(200),
    );

    完整的示例在这个提交中:https://github.com/schauder/so-sd-jdbc-multipleonetoone/tree/5570979ef85e30fe7a17a8ce48d867fdb79e212a .

  3. 有两个独立的Engine 类和表。一个用于汽车,一个用于卡车

  4. 如果您不想或不能更改数据库架构,您可以考虑 EngineCarTruck三个独立的聚合体。您将在 CarTruck 中有一个 Long engineId。然后可以使用 event listener for AfterDeleteEvent 完成级联删除。 .

关于java - 如何与 Spring Data JDBC 建立一对一关系模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53611326/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com