将列表组合并迁移到DTO层的最佳方法是什么?

时间:2017-08-03 04:23:03

标签: java spring hibernate-mapping

我在树形结构中有完整列表,

类别实体类:

@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 Structure:

[
  {
    "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
      }
    ]
  }
]
  

类别---&GT;所属分类---&GT;产品列表---&GT;产品列表

这高于我所拥有的,我需要的一切,只想将两个产品列表合并并合并到一个列表并传递到DTO层,

我的DTO课程将是:

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
      }
    ]
  }
]

这样做的最佳方法是什么?我可以在这里使用递归吗?任何人请帮助我提前谢谢。

根据答案,我更新了我的问题,但数据仍未正确映射,我需要做些什么更改,请帮助我。

这是我更新的控制器类

@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类中的方法,我可以将数据设置为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;

    }
    }

3 个答案:

答案 0 :(得分:0)

尝试使用Jackson进行JSON到Java对象的转换。您可能需要简单的注释来进行序列化和反序列化。

https://github.com/FasterXML/jackson

答案 1 :(得分:0)

要求最好的方法是基于意见(这是Stack Overflow的主题)。但是,一种可能的方法是递归到#34; flatten&#34;这些列表是使用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()会返回Stream<Stream<Product>>,而flatMap()会将所有这些流合并为一个Stream<Product> }}

由于此方法将返回流而不是列表,因此您应该使用以下命令将其收集到某个列表中:

List<Product> listOfAllProducts = getProducts(category).collect(Collectors.toList());

答案 2 :(得分:0)

简单地说,您可以使用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;


}