在 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 中检索外键属性的主要内容,如果未能解决你的问题,请参考以下文章
给springmvc接口快速增加字段检索,外键从表检索,外键从表查询的searchdb注解