天天看点

JPA一对多,多对一双向关联

下面是一个订单与订单项的配置。

级联操作与懒加载的配置在注释里面有详细的描述。

订单(Order):

@Entity
@Table(name="orders")
public class Order {
    
    @Id
    @Column(length=40)
    private String orderId;        //订单ID
    
    @Column(nullable=false)
    private Float amount = 0f;    //总价
/* 
     * cascade={CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE}
     * 级联刷新:当获取最新的订单记录时,是否获取最新的订单项记录
     * 级联保存:当保存Order的时候,需不需要对对Order下面的OrderItem进行保存 
     * 级联合并(更新):当Order处于游离态的时候,如果更新Order时,items修改了,是否把OrderItem同步更新到数据库
     * 级联删除:当删除Order时,是否对Order里面的所有OrderItem也执行删除操作(顺序是:先删除订单项,再删除订单)
     * 
     * 注意:1只用调用refresh()方法时,级联刷新才起作用
     *        只有调用persist()方法时,级联保存才起作用
     *        只用调用merge()方法时,级联更新才起作用
     *        只用调用delete()方法时,级联删除才起作用
     *       2需要用到级联刷新的情形:当我们获取到一条记录后,在对这个记录操作的时候,有人把这条记录修改了,如果我们想拿到最新的数据,必须调用refresh()方法
     *        即使调用find()方法也获取不到最新的数据,因为再次调用find()方法是,是从EntityManager的一级缓存中取数据。
     *        如:EntityManager em = factory.createEntityManager();
     *         Person person = em.find(Person.class,1)
     *         em.refresh();
     *         System.out.println(person);
     *     
     */
    
    /*
     * fetch=FetchType.EAGER    fetch=FetchType.LAZY
     * 如果希望获取Order的时候,立即获取OrderItem集合,用FetchType.EAGER
     * 如果希望获取Order的时候,并不需要立即获取OrderItem集合,只有访问items属性并对其操作的时候才获取,用FetchType.LAZY
     * 
     * 注意: 1.访问延迟属性时,EntityManger必须是打开状态,否则会抛出延迟加载例外
     *     2.如果是得到多的一方,默认的是延迟加载,例如:OneToMany
     *       如果是得到一的一方,默认的是立即加载,例如:OneToOne,ManyToOne
     */
    
    /*
     * mappedBy申明了这个类为关系被维护端,指明了在关系维护端由哪一个属性维护这个关系。
     * 相当于Hibernate中:
     * <set name="item" inverse=true>
     * </set>
     */
    @OneToMany(cascade={CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},
            fetch=FetchType.LAZY,mappedBy="order")
    private Set<OrderItem> items = new HashSet<OrderItem>();
    
    public String getOrderId() {
        return orderId;
    }
    
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
    public Float getAmount() {
        return amount;
    }
    
    public void setAmount(Float amount) {
        this.amount = amount;
    }

    public Set<OrderItem> getItems() {
        return items;
    }

    public void setItems(Set<OrderItem> items) {
        this.items = items;
    }
           

订单项(OrderItem):

@Entity
public class OrderItem {
	
	@Id
	@GeneratedValue	//ID自增长
	private Integer id;
	
	@Column(length=40,nullable=false)
	private String productName;

	@Column(nullable=false)
	private Float sellPrice;
	
	/*
	 * 级联保存:一般来说不需要,不可能保存某一个订单项的时候就保存订单
	 * 级联更新:需要,如果改变了订单项的价格,一般来说需要改变订单的总价
	 * 级联刷新:当获取订单项的最新记录时,是否需要获取订单的最新记录
	 * 级联删除:不需要
	 */
	
	/*
	 * 加载行为:默认是立即加载
	 */
	
	/*
	 * optional=true 表示可选,即外键字段可以为空
	 * optional=false 表示不可选,即外键字段不为空
	 */
	
	/*
	 * @JoinColumn(name="order_id")	数据库中外键的名字为order_id
	 */
	@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},
			fetch=FetchType.EAGER,optional=false)
	@JoinColumn(name="order_id")
	private Order order;
	
	public Integer getId() {
		return id;
	}
	
	public void setId(Integer id) {
		this.id = id;
	}
	public String getProductName() {
		return productName;
	}
	
	public void setProductName(String productName) {
		this.productName = productName;
	}
	public Float getSellPrice() {
		return sellPrice;
	}
	
	public void setSellPrice(Float sellPrice) {
		this.sellPrice = sellPrice;
	}

	public Order getOrder() {
		return order;
	}

	public void setOrder(Order order) {
		this.order = order;
	}