在 DTO 中检索外键属性

Posted

技术标签:

【中文标题】在 DTO 中检索外键属性【英文标题】:Retrieving foreign key attributes in DTO 【发布时间】:2020-06-18 13:04:48 【问题描述】:

我正在使用 java+Spring 框架+Hibernate 来创建 rest api,但我偶然发现了使用外键属性检索表的详细信息。 我有以下表格::

https://i.stack.imgur.com/lG7UR.png

我正在检索使用产品 ID 给出的所有评级,然后映射到 DTO,现在我还想使用 idusers 填充用户名,因为这是我的外键。

当我尝试检索用户给出的评分时也是如此,而不是显示 idproducts 我想显示产品名称和产品描述,因为它是一个外键。

关于如何使用 DTO 的任何建议。

【问题讨论】:

分享一些你正在尝试的代码 我意识到我只需要简单地使用 UserDTO 对象来检索用户 ID,然后访问 UserDTO 字段来检索用户名 【参考方案1】:

在将 DTO 转换为实体 bean 以及从实体 bean 转换为 DTO 时,您可以使用 ModelMapper。

将 ModelMapper 添加到您的项目中

<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.5</version>
</dependency>

在 Spring 配置中定义 ModelMapper bean

@Bean
public ModelMapper modelMapper() 
return new ModelMapper();

根据您给出的给定 ER 图假设以下模型

public class UserDto 
Integer userId;
String role;
String username;
String password;
boolean enabled;
...default and parameterized constructor
...getter and setter methods



public class ProductDto 
Integer productId;
String imageUrl;
String category;
int productPrice;
int productQuantity;
String productName;
String productDesc;
...default and parameterized constructor
...getter and setter methods



public class RatingDto 
@Id
Integer id;
int rating;
String review;
String ratingscol;
ProductDto productDto;
UserDto userDto;
...default and parameterized constructor
...getter and setter methods

您可以通过以下方法使用产品 ID 和用户详细信息检索产品的评级

 @Repository
 public interface RatingRepository extends JpaRepository<Rating, Integer>
 List<Rating> findByProduct_ProductId(Integer productId);
 

然后将评级对象映射到 DTO

 RatingDto ratingDto = modelMapper.map(rating, RatingDto.class);

现在您可以按以下方式检索用户名

 ratingsDto.getUserDto().getUserName()

与通过 userId 检索评级和访问产品详细信息的方式相同

【讨论】:

【参考方案2】:

这是Blaze-Persistence Entity Views 的完美用例。

Blaze-Persistence 是基于 JPA 的查询构建器,它支持 JPA 模型之上的许多高级 DBMS 功能。我在它之上创建了实体视图,以允许在 JPA 模型和自定义接口定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您以您喜欢的方式定义您的目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您通常不需要显式映射,因为 80% 的用例是拥有作为实体模型子集的 DTO。

假设你有一个这样的实体模型

@Entity
public class User 
    @Id
    Integer id;
    String role;
    String username;
    String password;
    boolean enabled;


@Entity
public class Product 
    @Id
    Integer id;
    String imageUrl;
    String category;
    int productPrice;
    int productQuantity;
    String productName;
    String productDesc;
    @OneToMany(mappedBy = "product")
    Set<Rating> ratings;


@Entity
public class Rating 
    @Id
    Integer id;
    int rating;
    String review;
    String ratingscol;
    @ManyToOne(fetch = LAZY)
    Product product;
    @ManyToOne(fetch = LAZY)
    User user;

模型的 DTO 映射可能如下所示简单

@EntityView(Rating.class)
interface RatingDto 
    Integer getId();
    UserDto getUser();
    ProductDto getProduct();

@EntityView(User.class)
interface UserDto 
    Integer getId();
    String getUsername();

@EntityView(Rating.class)
interface ProductDto 
    Integer getId();
    String getProductName();
    String getProductDesc();

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

RatingDto dto = entityViewManager.find(entityManager, RatingDto.class, id);

但是 Spring Data 集成允许您几乎像 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

它只会获取您告诉它获取的映射

【讨论】:

这是我想要使用的,它不仅为我们提供了优于惰性配置的优势,而且在性能方面也有优势。非常感谢!

以上是关于在 DTO 中检索外键属性的主要内容,如果未能解决你的问题,请参考以下文章

在c# app中,如何在SQL中连接子任务表的外键?

DTO对象

如何从外键表中检索值?

给springmvc接口快速增加字段检索,外键从表检索,外键从表查询的searchdb注解

给springmvc接口快速增加字段检索,外键从表检索,外键从表查询的searchdb注解

从没有外键的两个模型的 JOIN 中检索值(Django)