在 DTO 中检索外键属性
Retrieving foreign key attributes in DTO
我正在使用 java+Spring framework+Hibernate 来创建 rest api 但我偶然发现使用外键属性检索 table 的详细信息。
我有以下 tables::
https://i.stack.imgur.com/lG7UR.png
我正在检索使用产品 ID 给出的所有评级,然后映射到 DTO,现在我还想使用 idusers 填充用户名,因为这是我的外键。
当我尝试检索用户给出的评分时也是如此,我不想显示 idproducts,而是想显示产品名称和产品描述,因为它是外键。
有关如何使用 DTO 执行此操作的任何建议。
这是 Blaze-Persistence Entity Views 的完美用例。
Blaze-Persistence 是基于 JPA 的查询构建器,它支持基于 JPA 模型的许多高级 DBMS 功能。我在它之上创建了实体视图,以允许在 JPA 模型和自定义接口定义的模型之间轻松映射,类似于 Spring 类固醇数据投影。这个想法是您按照自己喜欢的方式定义目标结构,并通过 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 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
它只会获取您告诉它获取的映射
在将 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()
与您通过用户 ID 检索评分和访问产品详细信息的方式相同
我正在使用 java+Spring framework+Hibernate 来创建 rest api 但我偶然发现使用外键属性检索 table 的详细信息。 我有以下 tables::
https://i.stack.imgur.com/lG7UR.png
我正在检索使用产品 ID 给出的所有评级,然后映射到 DTO,现在我还想使用 idusers 填充用户名,因为这是我的外键。
当我尝试检索用户给出的评分时也是如此,我不想显示 idproducts,而是想显示产品名称和产品描述,因为它是外键。
有关如何使用 DTO 执行此操作的任何建议。
这是 Blaze-Persistence Entity Views 的完美用例。
Blaze-Persistence 是基于 JPA 的查询构建器,它支持基于 JPA 模型的许多高级 DBMS 功能。我在它之上创建了实体视图,以允许在 JPA 模型和自定义接口定义的模型之间轻松映射,类似于 Spring 类固醇数据投影。这个想法是您按照自己喜欢的方式定义目标结构,并通过 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 数据集成让您几乎可以像 Spring 数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
它只会获取您告诉它获取的映射
在将 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()
与您通过用户 ID 检索评分和访问产品详细信息的方式相同