合并列表并迁移到 DTO 层的最佳方法是什么?
What is the best way to combine the list and migrate to DTO layer?
我有完整的树结构列表,
类别实体 class :
@Entity
@Table(name = Category1.TABLE_NAME, indexes = { @Index(columnList = Category.COLUMN_CATEGORY_ID, unique = true) })
public class Category1 {
public static final String TABLE_NAME = "BB_Category1";
public static final String COLUMN_CATEGORY_ID = "pk_category_id";
public static final String COLUMN_CATEGORY_NAME = "category_name";
public static final String COLUMN_CATEGORY_FOREIGN_KEY = "fk_parent_category_id";
public static final String COLUMN_MAIN_PARENT_CATEGORY_ID = "main_parent_category_id";
public static final String USER_ADDED_BY_FOREIGN_KEY = "fk_added_by";
public static final String USER_MODIFIED_BY_FOREIGN_KEY = "fk_modified_by";
public static final String COLUMN_MODIFIED_ON = "modified_on";
public static final String COLUMN_CATEGORY_STATUS = "status";
public static final String TABLE_PRODUCT_CATEGORY = "BB_Product_category1";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = COLUMN_CATEGORY_ID)
private int categoryId;
@Column(name = COLUMN_CATEGORY_NAME, columnDefinition = "VARCHAR(255)", nullable = false)
private String categoryName;
@Column(name = COLUMN_MAIN_PARENT_CATEGORY_ID, columnDefinition = "INT(10)", nullable = true)
private Integer mainCategoryId;
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = COLUMN_CATEGORY_FOREIGN_KEY, nullable = true)
@Where(clause="status=1")
private List<Category1> categories;
@Column(name = USER_MODIFIED_BY_FOREIGN_KEY, nullable = true)
private int updatedBy;
@Column(name = USER_ADDED_BY_FOREIGN_KEY, nullable = true)
private int createdBy;
@Column(name = COLUMN_CATEGORY_STATUS, columnDefinition = "TINYINT(1) DEFAULT 1", nullable = false)
private int status;
//@LazyCollection(LazyCollectionOption.FALSE)
//@ElementCollection(targetClass = Category.class)
@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name = TABLE_PRODUCT_CATEGORY, joinColumns = @JoinColumn(name = COLUMN_CATEGORY_ID), inverseJoinColumns = @JoinColumn(name = ProductService1.COLUMN_PRODUCT_ID))
@Where(clause="status=1")
private List<ProductService1> productService1;
//Setter Getter
}
我得到以下 Json 结构:
[
{
"categoryId": 60,
"categoryName": "Category1",
"categories": [
{
"categoryId": 61,
"categoryName": "Category2",
"mainCategoryId": 60,
"categories": [],
"updatedBy": 1,
"createdBy": 1,
"status": 1,
"productService1": [
{
"productId": 61,
"productName": "ProductP2",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
],
"productService1": [
{
"productId": 60,
"productName": "ProductP1",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
]
Category--->CategoryList--->ProductList--->ProductList
这超出了我所拥有的,这是我需要的一切,只是想合并两个产品列表并合并到一个列表并传递给 DTO 层,
我的 DTO class 将是:
public class Category1Model {
private String categoryName;
private int mainCategoryId;
private int updatedBy;
private int createdBy;
private int status;
List<Category2Model> categoryList;
List<ProductService1> productList;
//setter Getter
}
预期Json格式:
[
{
"categoryId": 60,
"categoryName": "Category1",
"categories": [
{
"categoryId": 61,
"categoryName": "Category2",
"mainCategoryId": 60,
"categories": [],
"updatedBy": 1,
"createdBy": 1,
"status": 1
}
],
"productService1": [
{
"productId": 60,
"productName": "ProductP1",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
},
{
"productId": 61,
"productName": "ProductP2",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
]
最好的方法是什么?我可以在这里使用递归吗?任何人都请帮助我在此先感谢。
根据回答我更新了我的问题,但数据仍然没有正确映射,我需要做哪些更改请帮助我。
这是我更新的控制器 class
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Category1Model> getCategory() {
List<ProductService1> listOfAllProducts = new ArrayList<>();
List<Category1> list =productCatService1.getCategory();
int i=0;
for(Category1 cat:list)
{
System.out.println("@%$#%$@%#%@$@%$$ "+i++);
listOfAllProducts = getProducts(cat).collect(Collectors.toList());
}
return Category1Model.createModels(list, listOfAllProducts);
}
private Stream<ProductService1> getProducts(Category1 category) {
return Stream.concat(category.getProductService1().stream(), category.getCategories().stream().flatMap(this::getProducts));
}
这是我在 DTO class 中的方法,我可以在其中将数据设置到 dto 层:
public static List<Category1Model> createModels(List<Category1> entitys,List<ProductService1> productList) {
List<Category1Model> models = new ArrayList<>();
if (entitys == null || entitys.isEmpty()) {
return models;
}
entitys.parallelStream().forEach(entity -> models.add(createModel(entity,productList)));
return models;
}
public static Category1Model createModel(Category1 entity, List<ProductService1> productList) {
if (entity == null) {
return null;
}
Category1Model model = new Category1Model();
model.setCategoryId(entity.getCategoryId());
model.setCategoryName(entity.getCategoryName());
model.setProductList(productList);
model.setCategoryList(Category2Model.createModels(entity.getCategories()));
return model;
}
}
尝试 Jackson 进行 JSON 到 Java 的对象转换。您可能需要用于序列化和反序列化的简单注释。
寻求最佳方法将基于意见(这与 Stack Overflow 无关)。但是对 "flatten" 这些列表进行递归的一种可能方法是使用 Java 8 streams:
例如:
private Stream<Product> getProducts(Category category) {
return Stream.concat(category.getProducts().stream(), category.getCategories().stream().flatMap(this::getProducts));
}
Stream.concat()
用于将多个流连接成一个流。在这种情况下,我们使用它来连接:
- 当前类别的产品流(
category.getProducts().stream()
)
- 下一级的产品流(这里使用递归)
递归发生在第二个参数 (category.getCategories().stream().flatMap(this::getProducts)
) 中。基本上我们创建一个子类别流,然后通过调用 getProducts()
方法将其映射到它的产品。
我们在这里使用 flatMap()
的原因是因为 map()
会 return 一个 Stream<Stream<Product>>
而 flatMap()
将所有这些流合并到一个单身Stream<Product>
.
由于此方法将 return 一个流而不是一个列表,您应该使用以下方法将其收集到某处的列表中:
List<Product> listOfAllProducts = getProducts(category).collect(Collectors.toList());
简单来说,你可以使用Hashmap将多个对象放入DTO。
class CommonDTO{
private Map dataMap;//create getters and setters
}
如下设置commonDto
public CommonDTOsomeName()
{
CommonDTO commonDto=new CommonDTO();
Map dataMap=new HashMap();
dataMap.put(categoryList");
dataMap.put(productList");
commonDto.setDataMap(dataMap);
return commonDto;
}
我有完整的树结构列表,
类别实体 class :
@Entity
@Table(name = Category1.TABLE_NAME, indexes = { @Index(columnList = Category.COLUMN_CATEGORY_ID, unique = true) })
public class Category1 {
public static final String TABLE_NAME = "BB_Category1";
public static final String COLUMN_CATEGORY_ID = "pk_category_id";
public static final String COLUMN_CATEGORY_NAME = "category_name";
public static final String COLUMN_CATEGORY_FOREIGN_KEY = "fk_parent_category_id";
public static final String COLUMN_MAIN_PARENT_CATEGORY_ID = "main_parent_category_id";
public static final String USER_ADDED_BY_FOREIGN_KEY = "fk_added_by";
public static final String USER_MODIFIED_BY_FOREIGN_KEY = "fk_modified_by";
public static final String COLUMN_MODIFIED_ON = "modified_on";
public static final String COLUMN_CATEGORY_STATUS = "status";
public static final String TABLE_PRODUCT_CATEGORY = "BB_Product_category1";
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = COLUMN_CATEGORY_ID)
private int categoryId;
@Column(name = COLUMN_CATEGORY_NAME, columnDefinition = "VARCHAR(255)", nullable = false)
private String categoryName;
@Column(name = COLUMN_MAIN_PARENT_CATEGORY_ID, columnDefinition = "INT(10)", nullable = true)
private Integer mainCategoryId;
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = COLUMN_CATEGORY_FOREIGN_KEY, nullable = true)
@Where(clause="status=1")
private List<Category1> categories;
@Column(name = USER_MODIFIED_BY_FOREIGN_KEY, nullable = true)
private int updatedBy;
@Column(name = USER_ADDED_BY_FOREIGN_KEY, nullable = true)
private int createdBy;
@Column(name = COLUMN_CATEGORY_STATUS, columnDefinition = "TINYINT(1) DEFAULT 1", nullable = false)
private int status;
//@LazyCollection(LazyCollectionOption.FALSE)
//@ElementCollection(targetClass = Category.class)
@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name = TABLE_PRODUCT_CATEGORY, joinColumns = @JoinColumn(name = COLUMN_CATEGORY_ID), inverseJoinColumns = @JoinColumn(name = ProductService1.COLUMN_PRODUCT_ID))
@Where(clause="status=1")
private List<ProductService1> productService1;
//Setter Getter
}
我得到以下 Json 结构:
[
{
"categoryId": 60,
"categoryName": "Category1",
"categories": [
{
"categoryId": 61,
"categoryName": "Category2",
"mainCategoryId": 60,
"categories": [],
"updatedBy": 1,
"createdBy": 1,
"status": 1,
"productService1": [
{
"productId": 61,
"productName": "ProductP2",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
],
"productService1": [
{
"productId": 60,
"productName": "ProductP1",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
]
Category--->CategoryList--->ProductList--->ProductList
这超出了我所拥有的,这是我需要的一切,只是想合并两个产品列表并合并到一个列表并传递给 DTO 层,
我的 DTO class 将是:
public class Category1Model {
private String categoryName;
private int mainCategoryId;
private int updatedBy;
private int createdBy;
private int status;
List<Category2Model> categoryList;
List<ProductService1> productList;
//setter Getter
}
预期Json格式:
[
{
"categoryId": 60,
"categoryName": "Category1",
"categories": [
{
"categoryId": 61,
"categoryName": "Category2",
"mainCategoryId": 60,
"categories": [],
"updatedBy": 1,
"createdBy": 1,
"status": 1
}
],
"productService1": [
{
"productId": 60,
"productName": "ProductP1",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
},
{
"productId": 61,
"productName": "ProductP2",
"productDescription": "111",
"productNote": "111",
"productPrice": 111,
"productMaintenance": 111,
"status": 1
}
]
}
]
最好的方法是什么?我可以在这里使用递归吗?任何人都请帮助我在此先感谢。
根据回答我更新了我的问题,但数据仍然没有正确映射,我需要做哪些更改请帮助我。
这是我更新的控制器 class
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Category1Model> getCategory() {
List<ProductService1> listOfAllProducts = new ArrayList<>();
List<Category1> list =productCatService1.getCategory();
int i=0;
for(Category1 cat:list)
{
System.out.println("@%$#%$@%#%@$@%$$ "+i++);
listOfAllProducts = getProducts(cat).collect(Collectors.toList());
}
return Category1Model.createModels(list, listOfAllProducts);
}
private Stream<ProductService1> getProducts(Category1 category) {
return Stream.concat(category.getProductService1().stream(), category.getCategories().stream().flatMap(this::getProducts));
}
这是我在 DTO class 中的方法,我可以在其中将数据设置到 dto 层:
public static List<Category1Model> createModels(List<Category1> entitys,List<ProductService1> productList) {
List<Category1Model> models = new ArrayList<>();
if (entitys == null || entitys.isEmpty()) {
return models;
}
entitys.parallelStream().forEach(entity -> models.add(createModel(entity,productList)));
return models;
}
public static Category1Model createModel(Category1 entity, List<ProductService1> productList) {
if (entity == null) {
return null;
}
Category1Model model = new Category1Model();
model.setCategoryId(entity.getCategoryId());
model.setCategoryName(entity.getCategoryName());
model.setProductList(productList);
model.setCategoryList(Category2Model.createModels(entity.getCategories()));
return model;
}
}
尝试 Jackson 进行 JSON 到 Java 的对象转换。您可能需要用于序列化和反序列化的简单注释。
寻求最佳方法将基于意见(这与 Stack Overflow 无关)。但是对 "flatten" 这些列表进行递归的一种可能方法是使用 Java 8 streams:
例如:
private Stream<Product> getProducts(Category category) {
return Stream.concat(category.getProducts().stream(), category.getCategories().stream().flatMap(this::getProducts));
}
Stream.concat()
用于将多个流连接成一个流。在这种情况下,我们使用它来连接:
- 当前类别的产品流(
category.getProducts().stream()
) - 下一级的产品流(这里使用递归)
递归发生在第二个参数 (category.getCategories().stream().flatMap(this::getProducts)
) 中。基本上我们创建一个子类别流,然后通过调用 getProducts()
方法将其映射到它的产品。
我们在这里使用 flatMap()
的原因是因为 map()
会 return 一个 Stream<Stream<Product>>
而 flatMap()
将所有这些流合并到一个单身Stream<Product>
.
由于此方法将 return 一个流而不是一个列表,您应该使用以下方法将其收集到某处的列表中:
List<Product> listOfAllProducts = getProducts(category).collect(Collectors.toList());
简单来说,你可以使用Hashmap将多个对象放入DTO。
class CommonDTO{
private Map dataMap;//create getters and setters
}
如下设置commonDto
public CommonDTOsomeName()
{
CommonDTO commonDto=new CommonDTO();
Map dataMap=new HashMap();
dataMap.put(categoryList");
dataMap.put(productList");
commonDto.setDataMap(dataMap);
return commonDto;
}