【发布时间】:2020-10-31 14:59:29
【问题描述】:
我正在创建一个库存管理系统。向内库存将是产品和相应数量的集合。因此,InwardInventory 和 InwardOutwardList 之间是一对多的。
public class InwardOutwardList extends ReusableFields
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long entryid;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="productId",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Product product;
Double quantity;
//getter setter
}
进货库存
public class InwardInventory extends ReusableFields implements Cloneable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="inwardid")
Long inwardid;
@NonNull
String vehicleNo;
@ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "inwardinventory_entry", joinColumns = {
@JoinColumn(name = "inwardid", referencedColumnName = "inwardid") }, inverseJoinColumns = {
@JoinColumn(name = "entryId", referencedColumnName = "entryId") })
Set<InwardOutwardList> inwardOutwardList = new HashSet<>();;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="warehouse_id",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Warehouse warehouse;
因此,当我获取包含两个产品 iron 和水泥的单个内向库存时,我会收到如下嵌套 json 格式的数据
[{
"inwardid": 19497,
"vehicleNo": "TRUCK",
"inwardOutwardList": [
{
"entryid": 19499,
"product": {
"productName": "Cement"
},
"quantity": 100
},
{
"entryid": 19500,
"product": {
"productName": "Iron"
},
"quantity": 10
}
],
"warehouse": {
"warehouseName": "war2"
},
"supplier": {
"name": "Bright Traders"
}
}]
现在,我想将其导出为 csv。所以,我需要把它展平,只有一个像下面这样的级别
[
{
"inwardid": 19497,
"vehicleNo": "TRUCK",
"productName": "Cement",
"quantity": 100,
"warehouseName": "war2"
},
{
"inwardid": 19497,
"vehicleNo": "TRUCK",
"productName": "Iron",
"quantity": 10,
"warehouseName": "war2"
}
]
我编写了简单的嵌套 for-each 迭代,它正在发挥作用
private List<InwardInventoryExportFullDAO> transformStructure(List<InwardInventory> iiDataList)
{
List<InwardInventoryExportFullDAO> data = new ArrayList<InwardInventoryExportFullDAO>();
for(InwardInventory iiData:iiDataList)
{
for(InwardOutwardList ioList:iiData.getInwardOutwardList())
{
InwardInventoryExportFullDAO tempExportData = new InwardInventoryExportFullDAO();
tempExportData.setWarehouse(iiData.getWarehouse().getWarehouseName());
tempExportData.setVehicleNo(iiData.getVehicleNo());
tempExportData.setQuantity(ioList.getQuantity());
tempExportData.setProductName(ioList.getProduct().getProductName());
data.add(tempExportData);
}
}
return data;
}
但我认为如果内向库存记录数量激增,这不是最佳解决方案。我看到的另一个选项是使用并行流或 json 映射器。但我不确定哪个是实现这一目标的最佳和最佳解决方案。预计要导出 excel 的记录数在 10k 左右。
我已经编写的嵌套循环需要大约 5 秒来处理 2k 条记录。因此,将来负载增加时可能需要 30 多秒。所以,寻找最佳的最优解。
提前谢谢你
【问题讨论】:
-
对于 CSV,您使用的是什么库?
-
计划将此作为 Json 发送到前端。前端将进行导出
-
要展平嵌套的 Json,您可以编写自定义反序列化器并将所有 Json 字段映射到平面对象。
-
@KevKosDev。我试着这样做。但我面临的问题是一对多映射。我需要来自父对象的 2 个字段和来自子对象列表的两个字段。父母的字段应该为每个孩子重复。所以,这是一种父子之间的交叉连接。我无法弄清楚如何实现这一目标。
-
这是个坏主意,因为前端需要再次处理,而且我认为您当前的解决方案效率很高,可以进行一些小的修改,例如使用构造函数/构建器进行 DTO 和 2k 记录 5 秒也许还有别的需要时间。对于 10k 数据,处理它最多需要 1 秒。
标签: spring-boot spring-mvc jpa spring-data-jpa java-stream