下面的Java Project,演示一对多映射
首先是订单的实体Bean
package com.jadyer.model; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; /** * 订单的实体Bean * @see 三个属性对应的setter和getter略 */ @Entity @Table(name="orders") //默认的表名order与MySQL关键字冲突 public class Order { @Id @Column(length=12) private String orderid; //订单号,在实际使用中应该把它设成String型 @Column(nullable=false) private Float amount = 0f; //订单的总价,默认为0 //在OneToMany和ManyToMany中,只要是加载多的一方,那么它的延迟属性的默认值就是延迟加载,即fetch=FetchType.LAZY。共同点是后面都是ToMany //在ManyToOne和OneToOne中,只要是加载一的一方,那么它的延迟属性的默认值就是立即记载,即fetch=FetchType.EAGER。。共同点是后面都是ToOne @OneToMany(cascade={CascadeType.REFRESH, CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy="order") private Set<OrderItem> items = new HashSet<OrderItem>(); public void addOrderItem(OrderItem orderItem){ orderItem.setOrder(this); //因为OrderItem是关系维护端 this.items.add(orderItem); } } /************************************************************************************************************************/ //CascadeType.REFRESH-->级联刷新 //CascadeType.PERSIST-->级联持久化,或者叫做级联保存。当保存对象时,同时保存该对象的子对象 //CascadeType.MERGE---->级联合并,也可以叫做级联更新。当更新对象时,同时更新该对象的子对象 //CascadeType.REMOVE--->级联删除。。。。。。。。。。。当删除对象时,同时删除该对象的子对象 //注意:CascadeType.REFRESH只适用于实体管理器的refresh()方法 //注意:CascadeType.PERSIST只适用于实体管理器的persist()方法 //注意:CascadeType.MERGE只适用于实体管理器的merge()方法 //注意:CascadeType.REMOVE只适用于实体管理器的remove()方法,并且对于JPQL中的delete from...是不会起作用的 //小结:也就是说这里的四个级联类型,是与实体管理器EntityManager的四个方法一一对应的,而与JPQL无关 /************************************************************************************************************************/ //在JPA规范中,如果是一对多或者多对一关系的话,那么多的一方为关系维护端 //关系维护端负责外键记录的更新,关系被维护端是没有权利更新外键字段的 //这里mappedBy属性,等于是声明了该类为关系的被维护端 //mappedBy的值指定的就是关系维护端中维护该关系的属性,类似于Hibernate中的inverse="true"属性 //这里mappedBy="order"里面的order对应的是OrderItem.java中的order属性 /************************************************************************************************************************/
然后是订单项的实体Bean
package com.jadyer.model; 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; /** * 订单项的实体Bean * @see 四个属性对应的setter和getter略 */ @Entity public class OrderItem { @Id @GeneratedValue private Integer id; @Column(length=40, nullable=false) private String productName; //产品名称 @Column(nullable=false) private Float sellPrice = 0f; //销售价,初值为0 //若optional=false就代表order的值是必须存在的,反映在数据库中的外键字段的值就是禁止为空 @ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH}, optional=false) @JoinColumn(name="order_id") //指定外键的名称。外键一般都是在关系维护端定义 private Order order; }
用到的位于classpath下的META-INF下的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="jadyerJPAOneToMany" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" /> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" /> <property name="hibernate.connection.username" value="scott" /> <property name="hibernate.connection.password" value="jadyer" /> <property name="hibernate.connection.url" value="jdbc:oracle:thin:@127.0.0.1:1521:jadyer" /> </properties> </persistence-unit> </persistence>
最后用到的是JUnit4单元测试类OneToManyTest.java
package com.jadyer.junit; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; import com.jadyer.model.Order; import com.jadyer.model.OrderItem; public class OneToManyTest { @Test public void save(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("jadyerJPAOneToMany"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); //开启事务 OrderItem orderItem11 = new OrderItem(); OrderItem orderItem22 = new OrderItem(); orderItem11.setProductName("九阴真经"); orderItem11.setSellPrice(46f); orderItem22.setProductName("六脉神剑"); orderItem22.setSellPrice(36f); Order order = new Order(); order.setOrderid("999"); order.setAmount(orderItem11.getSellPrice() + orderItem22.getSellPrice()); order.addOrderItem(orderItem11); order.addOrderItem(orderItem22); em.persist(order); em.getTransaction().commit(); //提交事务 em.close(); factory.close(); } }
上面就是JPA中的一对多映射的示例工程
下面的是JPA中的一对一映射的示例工程
下面的Java Project,演示一对一映射
首先是身份证的实体Bean
package com.jadyer.model; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; /** * 身份证的实体Bean * @see 三个属性的setter和getter略 */ @Entity public class IDCard { @Id @GeneratedValue private Integer id; @Column(length=18, nullable=false) private String cardno; //身份证号 //当在Person.java中为IDCard设定非空之后,这里就不用再设置optional=false了 //在JPA规范中,并没有对一对一关系声明具体的关系维护端,所以我们可以人为的决定关系维护端 @OneToOne(mappedBy="idcard", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) private Person person; public IDCard(){} public IDCard(String cardno) { this.cardno = cardno; } }
然后是人的实体Bean
package com.jadyer.model; 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.OneToOne; /** * 人的实体Bean * @see 三个属性的setter和getter略 */ @Entity public class Person { @Id @GeneratedValue private Integer id; @Column(length=10, nullable=false) private String name; //姓名 @OneToOne(optional=false, cascade=CascadeType.ALL) @JoinColumn(name="idcard_id") private IDCard idcard; public Person(){} public Person(String name) { this.name = name; } }
该工程用到的persistence.xml与上面一对多示例中用的,相同,故略去
最后是用到的JUnit4单元测试类OneToOneTest.java
package com.jadyer.junit; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; import com.jadyer.model.IDCard; import com.jadyer.model.Person; public class OneToOneTest { @Test public void save(){ EntityManagerFactory factory = Persistence.createEntityManagerFactory("jadyerJPAOneToOne"); EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); //开启事务 Person person = new Person("沈浪"); person.setIdcard(new IDCard("222222")); em.persist(person); em.getTransaction().commit(); //提交事务 em.close(); factory.close(); } }