首页 > 代码库 > JPA开发总结<三>--一对多双向关联

JPA开发总结<三>--一对多双向关联

学习JPA规范,也会涉及到关联关系的操作,对于使用注解方式的关联操作,这点就不如使用XML思路清晰明了,下面这是我总结的操作代码,注释说明很清楚,需要重点提的就是这里所有引得包都是sun提供的工具包,即javax.persistence.*,避免引包错误。

一对多关联从两点入手学习:JPA中的一对多双向关联与级联操作

                                                   JPA中的一对多延迟加载与关系维护

我们分析一对多,典型的例子就是订单和订单项的关系,一个订单有多个订单项,一个订单项指定一个订单id,详细看代码:

首先是Order类:

/**
 * JPA双向一对多关系的一的一端
 */
@Entity
@Table(name="t_order")
public class Order {

	@Id @Column(length=12)
	private String orderId;//人为赋值
	
	@Column(nullable=false)
	private Float amount = 0f;
	/**
	 * 要想CascadeType.PERSIST生效,必须调用refresh()方法
	 * 要想CascadeType.PERSIST生效,必须调用persist()方法
	 * 要想CascadeType.MERGE  生效,必须调用merge()  方法
	 * 要想CascadeType.REMOVE 生效,必须调用remove() 方法
	 * 
	 * FetchType.LAZY:延迟加载,必须保证EntityManager处于打开状态
	 * FetchType.EAGER:立即加载
	 * 如果To后面的是Many,那么不管To前的是什么,默认的是lazy加载策略(如OneToMany, ManyToMany)
	 * 反之,如果To后面的是One,那么默认的加载策略为eager立即加载
	 * 
	 * mappedBy:哪个类出现了mappedBy,这个类就是关系的被维护端
	 * @return
	 */
	@OneToMany(cascade=CascadeType.ALL,mappedBy="order")
	private Set<OrderItem> items = new HashSet<OrderItem>();
	
	public void addItems(OrderItem item){
		item.setOrder(this);//必须加上这句,因为关系的维护者是OrderItem
		this.items.add(item);
	}
	<!--get,set方法省略。。 -->
	
}

然后是OrderItem代码:

/**
 * JPA双向多对一关系的多的一端,
 * JPA规范规定:如果是双向的一对多关系,多的一方为关系维护端。
 * 关系维护端负责外键记录的更新,关系被维护端没有权利更新外键字段
 */
@Entity
@Table(name="t_orderItem")
public class OrderItem {

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(length=40,nullable=false)
	private String productName;
	
	@Column(nullable=false)
	private Float productPrice;
	/**
	 * 如果To后面的是One,那么默认的加载策略为eager立即加载
	 * optional表示该属性是不是可选的,即是否可以为null。(true表示可选,false表示不可选,即该对象必须存在)
	 * 
	 * JoinColumn表示外键
	 * @return
	 */
	@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)
	@JoinColumn(name="order_id")
	private Order order;
	
	public OrderItem() {
	}
	
	public OrderItem( String productName) {
		this.productName = productName;
	}
	<!-- set,get省略。。-->
}<span style="font-family:Microsoft YaHei;font-size:14px;">
</span>

最后编写测试类,使用Junit4.0测试:

public class OneToMany {

	private static EntityManagerFactory factory;
	private static EntityManager em;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		factory = Persistence.createEntityManagerFactory("jpatest1");
		em= factory.createEntityManager();
	}

	@Test
	public void saveOrder(){
		em.getTransaction().begin();
		Order order = new Order();
		order.setOrderId(UUID.randomUUID().toString().substring(0, 12));
		order.setAmount(120f);
		
		OrderItem item1 = new OrderItem();
		item1.setProductName("衣服");
		item1.setProductPrice(110f);
		
		OrderItem item2 = new OrderItem();
		item2.setProductName("零食");
		item2.setProductPrice(10f);
		
		order.addItems(item1);
		order.addItems(item2);
		//保存Order,不需要保存OrderItem,因为Order设置了级联保存
		em.persist(order);
		em.getTransaction().commit();
		em.close();
		factory.close();
	}
}
一对多整理到这,大体操作学习完毕。


JPA开发总结<三>--一对多双向关联