如何从一个对象集合中获取对象?

rkttyhzu  于 2021-06-29  发布在  Java
关注(0)|答案(3)|浏览(420)

我有一个 Order 实体和 OrderProduct . 我想显示在前端的订单细节,当然订购产品在它。那么如何从中获取产品对象呢 OrderProduct json。产品数组中缺少产品对象。我再也不需要order对象了,我认为它将是一个无限递归的东西
我的 Order 实体:

@Entity
@Getter
@Setter
@Table(name ="orders")
public class Order{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    private BigDecimal totalPrice;

    @OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JsonManagedReference(value="orders")
    private List<OrderProduct> products = new ArrayList<>();

    private int userId;

    @DateTimeFormat(pattern="dd/MM/yyyy")
    private Date date = new Date();

    @DateTimeFormat(pattern="dd/MM/yyyy")
    private Date deliveryDate;

    @Enumerated(EnumType.STRING)
    private OrderType orderType;

}

我的 OrderProduct 实体:

@Entity
@Setter
@Getter
public class OrderProduct {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JsonBackReference(value="product")
    @JoinColumn(name = "product_id")
    private Product product;

    @ManyToOne
    @JsonBackReference(value="orders")
    @JoinColumn(name = "order_id")
    private Order order;

    private Integer quantity;
}

产品实体:

@Entity
@Getter
@Setter
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String name;

    private double price;

    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    @JsonManagedReference(value="ingredients")
    private List<Ingredient> ingredients = new ArrayList<>();

    @OneToMany(mappedBy = "product",fetch = FetchType.EAGER)
    @JsonManagedReference(value="product")
    private List<OrderProduct> products = new ArrayList<>();

    private String fileName;

}

wqlqzqxt

wqlqzqxt1#

这可以由我的图书馆beanknife来完成

// This configure generate a class named ProductInfo which has the same shape with Product without property "products"
@ViewOf(value = Product.class, genName="ProductInfo", includePattern = ".*", excludes = {"products"})
class ProductInfoConfigure {}

// This configure generate a class named OrderProductRelation with the same shape of OrderProduct.
// But it has not order property and the type of its product property is change to ProductInfo generated above.
@ViewOf(value = OrderProduct.class, genName="OrderProductRelation", includePattern = ".*", excludes = {"order"})
class OrderProductRelationConfigure {
    @OverrideViewProperty("product")
    private ProductInfo product;
}

// This configure generate a class named OrderDetail with the same shape of Order. 
// But the type of its products property is change to List<OrderProductRelation>
@ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
class OrderDetailConfigure {
    @OverrideViewProperty("products")
    private List<OrderProductRelation> products;
}

将生成以下类:

class ProductInfo {
    private Long id;
    private String name;
    private double price;
    private List<Ingredient> ingredients; // it is not processed because you have not provide the class Ingredient
    private String fileName;
}

public class OrderProductRelation {
    private Long id;
    private ProductInfo product;
    private Integer quantity;
}

public class OrderDetail {
    public Long id;
    private BigDecimal totalPrice;
    private List<OrderProductRelation> products;
    private int userId;
    private Date date = new Date();
    private Date deliveryDate;
    private OrderType orderType;
}

然后

Order order = ...
OrderDetail orderDetail = OrderDetail.read(order);
// serialize the otherDetail instead of order.

List<Order> orders = ...
List<OrderDetail> orderDetails = OrderDetail.read(orders);
// serialize the orderDetails instead of orders.

可能的问题:
我没有使用lombok,所以可能需要对lombok进行调整,因为它可以动态地更改字节码。但这不是一个大问题,如果有人提出这个问题并提供足够的用例,我会尝试调整它。
生成的类不会继承原始类上的注解。在下一个版本中,我将提供一个sulotion。此时,作为一种解决方法,我们可以使用自定义方法手动转换属性。例如

@ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
class OrderDetailConfigure {
    @OverrideViewProperty("products")
    private List<OrderProductRelation> products;
    @OverrideViewProperty("orderType")
    public static String orderType(Order source) {
        return source.getOrder().name();
    }
}

生成的类将更改为

public class OrderDetail {
    public Long id;
    private BigDecimal totalPrice;
    private List<OrderProductRelation> products;
    private int userId;
    private Date date = new Date();
    private Date deliveryDate;
    private String orderType;
}

更新版本1.2.0已发布。添加对注解继承的支持。

@ViewOf(value = Order.class, genName="OrderDetail", includePattern = ".*")
@UseAnnotation({DateTimeFormat.class, Enumerated.class, JsonProperty.class})
class OrderDetailConfigure {
    @OverrideViewProperty("products")
    private List<OrderProductRelation> products;
}

生成

public class OrderDetail {
    public Long id;
    private BigDecimal totalPrice;
    private List<OrderProductRelation> products;
    private int userId;
    @DateTimeFormat(pattern="dd/MM/yyyy")
    private Date date;
    @DateTimeFormat(pattern="dd/MM/yyyy")
    private Date deliveryDate;
    @Enumerated(EnumType.STRING)
    private OrderType orderType;
}
noj0wjuj

noj0wjuj2#

这有助于用

@JsonIdentityInfo(
    property = "id",
    generator = ObjectIdGenerators.PropertyGenerator.class
)

每次json序列化进入循环时,对象数据都将替换为对象id或其他实体字段,供您选择。

wwodge7n

wwodge7n3#

你可以用 @JsonView 注解来定义需要序列化为json的字段
工作原理:
你需要用接口定义类。例如:

public class SomeView {

    public interface  id {}

    public interface CoreData extends id {}

    public interface FullData extends CoreData {}

}

将实体字段标记为 @JsonView(<some interface.class>) ```
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonView(SomeView.id.class)
private Long id;

@Column(nullable = false)
@JsonView(SomeView.CoreData.class)
private String username;

@Column(nullable = false)
@JsonView(SomeView.FullData.class)
private String email;

}

用注解端点 `@JsonView(<some interface.class>)` ```
@GetMapping()
 @JsonView(<some interface.class>)
 public User getUser() {
     return <get user entity somwhere>
 }

万一 @JsonView(SomeView.id.class) 您将得到以下json:

{
        id: <some id>
    }

万一 @JsonView(SomeView.CoreData.class) :

{
        id: <some id>,
        username: <some username>
    }

万一 @JsonView(SomeView.FullData.class) :

{
        id: <some id>,
        username: <some username>,
        email: <some email>
    }
``` `@JsonView` 也适用于嵌入对象,可以用多视图类注解一个字段- `@JsonView({SomeView.FullData.class, SomeOtherView.OtherData.class})` 在您的情况下,我认为您应该注解所有需要的字段,除了:

@OneToMany(mappedBy = "product",fetch = FetchType.EAGER)
@JsonManagedReference(value="product")
private List products = new ArrayList<>();

在 `Product` 避免循环序列化
或者,您也可以手动地使用dto类或seralize对象到json(https://thepracticaldeveloper.com/java-and-json-jackson-serialization-with-objectmapper/)

相关问题