JPA视频学习(三)双向一对多关联配置
1.persistence.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="JPAOneToManyPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name = "hibernate.connection.driver_class" value = "com.mysql.jdbc.Driver"/> <property name = "hibernate.connection.url" value = "jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8"/> <property name = "hibernate.connection.username" value = "root"/> <property name="hibernate.max_fetch_depth" value="3"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
2.配置实体:
Order实体:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="orders")
public class Order {
/**
* 双向的一对多关系里面,多的一方为关系的维护端。
* 关系的维护端负责外键字段(记录)的更新;
* 关系的被维护端是没有权力更新外键字段(记录)的。
*/
private String orderid;
private Float amount=0f;
private Set<OrderItem> items=new HashSet<OrderItem>();
@Id //需要人为赋值
@Column(length=12)
public String getOrderid() {
return orderid;
}
public void setOrderid(String orderid) {
this.orderid = orderid;
}
@Column(nullable=false)
public Float getAmount() {
return amount;
}
public void setAmount(Float amount) {
this.amount = amount;
}
public void setItems(Set<OrderItem> items) {
this.items = items;
}
/**
* CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE
* 是有应用条件的,即调用em.refresh,em.persist,em.merge,em.remove才有效。
* 如果是采用query的更新,删除和添加则是无效的。
*
* refresh是从数据库中获取最新的实体:
* 因为在em.find获得的实体和你要真正处理时可能相差一些时间,
* 这些时间里面,该实体可能被其他方法更新到数据库里面了,但是em缓存还没有变,
* 因此需要用refresh来获取最新的对象。
*
* //延迟加载必须保证em是开着的
//如果是ToMany则默认延迟加载
//如果是ToOne则默认是立即加载
//通过mappedBy声明关系的维护端,这里是指明在OrderItem类里面的哪个属性来维护关系
//在哪个类出现mappedBy则表明该实体是关系被维护端。
*/
@OneToMany(cascade={CascadeType.REFRESH,CascadeType.PERSIST
,CascadeType.MERGE,CascadeType.REMOVE}
,fetch=FetchType.LAZY
,mappedBy="order")
public Set<OrderItem> getItems() {
return items;
}
//建立关系维护
public void addOrderItem(OrderItem orderItem){
orderItem.setOrder(this);//关系维护端orderItem来设置,维护关系
this.items.add(orderItem);
}
}
OrderItem实体:
import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @Entity public class OrderItem { /** * 双向的一对多关系里面,多的一方为关系的维护端。 * 关系的维护端负责外键字段(记录)的更新; * 关系的被维护端是没有权力更新外键字段(记录)的。 */ private Integer id; private String productName; private Float priceFloat=0f; private Order order; public OrderItem(){ } public OrderItem(String string, float f) { this.priceFloat=f; this.productName=string; } public void setId(Integer id) { this.id = id; } @Id @GeneratedValue public Integer getId() { return id; } public void setProductName(String productName) { this.productName = productName; } @Column(length=40,nullable=false) public String getProductName() { return productName; } public void setPriceFloat(Float priceFloat) { this.priceFloat = priceFloat; } @Column(nullable=false) public Float getPriceFloat() { return priceFloat; } public void setOrder(Order order) { this.order = order; } //更新总价格 @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH} ,optional=false) //设置外键名称 @JoinColumn(name="orderid") public Order getOrder() { return order; } }
3.Junit测试:
package junit.test; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.BeforeClass; import org.junit.Test; import com.persia.bean.Order; import com.persia.bean.OrderItem; public class ManyToOneTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } //@Test public void save(){ EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); //此时数据库表已经建立,若没有表,很可能是实体的注解出错了。 EntityManager em=fac.createEntityManager(); em.getTransaction().begin(); Order order=new Order(); order.setAmount(34f); order.setOrderid("999"); order.addOrderItem(new OrderItem("足球",90f)); order.addOrderItem(new OrderItem("篮球",100f)); em.persist(order); em.getTransaction().commit(); em.close(); fac.close(); } //@Test public void getOrder(){ //读取不用开启事务 EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); Order o=em.find(Order.class, "999");//不存在返回null System.out.println(o.getOrderid()+":"+o.getAmount()); em.close(); fac.close(); } //@Test public void getOrderItemsByOrder(){ //读取不用开启事务 EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); Order o=em.find(Order.class, "999");//不存在返回null System.out.println(o.getOrderid()+":"+o.getAmount()); for(OrderItem otm:o.getItems()) System.out.println(otm.getProductName()+":"+otm.getPriceFloat()); em.close(); fac.close(); } //@Test public void getOrderItems(){ //读取不用开启事务 EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); OrderItem otm=em.find(OrderItem.class, 1);//不存在返回null System.out.println(otm.getProductName()+":"+otm.getPriceFloat()); System.out.println("order id:"+otm.getOrder().getOrderid()); em.close(); fac.close(); } //@Test public void updateOrder(){ EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); em.getTransaction().begin();//开启事务 Order order=em.find(Order.class, "999"); order.setAmount(1000f); em.merge(order);//用于把对处于游离状态的实体bean的更新同步到数据库。 em.getTransaction().commit();//提交事务 em.close(); fac.close(); } //@Test //级联更新 public void updateOrderCascade(){ EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); em.getTransaction().begin();//开启事务 Order order=em.find(Order.class, "999"); order.setAmount(2000f); for(OrderItem otm:order.getItems()){ otm.setPriceFloat(300f); } em.merge(order);//用于把对处于游离状态的实体bean的更新同步到数据库。 em.getTransaction().commit();//提交事务 em.close(); fac.close(); } @Test //级联删除 public void deleteOrder(){ EntityManagerFactory fac=Persistence.createEntityManagerFactory("JPAOneToManyPU"); EntityManager em=fac.createEntityManager(); em.getTransaction().begin();//开启事务 Order order=em.find(Order.class, "999"); em.remove(order); em.getTransaction().commit();//提交事务 em.close(); fac.close(); } }