gpt4 book ai didi

jpa - 从一个 View 映射具有嵌入式列表的实体

转载 作者:行者123 更新时间:2023-12-04 12:45:52 26 4
gpt4 key购买 nike

我正在尝试使用 spring-data-jpa 实现简单的 cqrs 应用程序所以我有 2 个表用来写 - 例如人和汽车(一个人可以有汽车 list )。我还使用创建为 select * from person join car 的一个 View ...

所以来自的示例查询可以给出输出(一个用户有 2 辆车)

firstName|lastName| car_brand | car_model |
marek |k | tesla | s |
marek |k | mercdes | 190 |

现在我正在尝试在 jpa 中映射此 View ,并且正在尝试嵌入列表

@Embeddable
class CarSnapshot {
private String carBrand;
private String carModel;
}

class PersonSnapshot {
private String firstName;
@Embedded // I tried also @OneToMany and ElementCollection
private Set<CarSnapshot> cars;
}

但这对我来说不起作用。你知道如何解决吗此外,一对一映射(一个人最多拥有一辆汽车)效果非常好

最佳答案

如果你想使用可嵌入类型,你可以执行以下操作:

@Entity
@Table(name = "persons")
public class Person {
@Id
private Integer id;

@ElementCollection
@CollectionTable(name = "person_cars", joinColumns = @JoinColumn(name = "person_id"), foreignKey = @ForeignKey(name = "person_cars_persons_fk"))
private List<PersonCar> cars;
}

@Embeddable
class PersonCar {

@Column(length = 32, nullable = false)
private String brand;

@Column(length = 32, nullable = false)
private String model;
}

在这种情况下,您的数据库架构可以是这样的:

create table persons (
id integer not null constraint persons_pkey primary key,
);

create table person_cars (
person_id integer not null constraint person_cars_persons_fk references persons,

brand varchar(32) not null,
model varchar(32) not null,

constraint supported_docs_pkey primary key (doc_type, country_code)
);

(这是 postgresql 方言)

更多信息在这里:Hibernate User Guide - Collections of value types

已更新

要将 View 映射到实体,您可以这样做:

@Data // It's Lombok annotation - c-tor, getters/setters etc.
@Entity
@Immutable
@IdClass(View.class)
@Subselect("select p.name as person_name, c.brand as car_brand, c.model as car_model from persons p join cars c on p.id = c.person_id")
public class View implements Serializable {

@Id private String personName;
@Id private String carBrand;
@Id private String carModel;
}

除了使用 @Subselect 注释,您还可以使用带有 View 名称的 @Table 注释:

@Data
@Entity
@Immutable
@IdClass(View.class)
@Table(name = "my_view")
public class View implements Serializable {...}

工作 demo .

更新 2

后处理的解决方法...

DTO:

@Value
public class PersonDto {
private String name;
private List<CarDto> cars = new ArrayList<>();

public PersonDto addCars(List<CarDto> cars) {
this.cars.addAll(cars);
return this;
}
}

@Value
public class CarDto {
private String brand;
private String model;
}

ViewRepo

public interface ViewRepo extends JpaRepository<View, View> {

List<View> findByPersonName(String name);

default PersonDto getPersonByName(String personName) {
return new PersonDto(personName)
.addCars(findByPersonName(personName)
.stream()
.map(p -> new CarDto(p.getCarBrand(), p.getCarModel()))
.collect(Collectors.toList()));
}
}

关于jpa - 从一个 View 映射具有嵌入式列表的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49025041/

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