合并列表并迁移到 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 的对象转换。您可能需要用于序列化和反序列化的简单注释。

https://github.com/FasterXML/jackson

寻求最佳方法将基于意见(这与 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;


}