在JPA的规范中,对于一对多可以有两种解释:OneToMany(一对多);ManyToOne(多对一)。其实这两个解释也就是看问题的角度不同而已,原理都是一样的。
应用场景:学生和公寓,从学生角度来看就是多对一;从公寓角度来看就是一对多。
ManyToOne:
学生实体:
package model;
import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table;
@Entity @Table(name="Student") public class Student {
@Id @Column(name="id") private int id; @Column(name="name") private String name; @Column(name="sex") private String sex;
@ManyToOne(cascade=CascadeType.ALL) @JoinColumn(name="Dept_Id") //设定映射名称(外键)为Dept_Id private Department department;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public Department getDepartment() { return department; }
public void setDepartment(Department department) { this.department = department; } } |
公寓实体:
package model;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;
@Entity @Table(name="Department") public class Department {
@Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) //自增 private long id;
@Column(name="name") private String name;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } } |
修改xml文件:
<?xml version="1.0" encoding="UTF-8"?> <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_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL"> <!-- <class>model.PersonInformation</class> --> <!-- <class>model.Person</class> --> <!-- <class>model.Employee2</class> <class>model.FamilyAddress2</class> --> <class>model.Student</class> <class>model.Department</class> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.81.129:3306/simpleDb" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="root" />
<!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence> |
测试类如下:
package main;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;
import model.Department; import model.Student;
public class StudentTest { private static final String PERSISTENCE_UNIT_NAME = "EmployeeService"; private static EntityManagerFactory factory;
public static void main(String[] args) { factory = Persistence.createEntityManagerFactory( PERSISTENCE_UNIT_NAME); EntityManager em = factory.createEntityManager(); //保证事务 em.getTransaction().begin();
Student student =new Student(); student.setName("David"); student.setSex("女");
Department department =new Department(); department.setName("孔子学院学生公寓");
student.setDepartment(department); em.persist(student); em.getTransaction().commit(); em.close(); } } |
运行结果如下:
可以看到在学生表中有一个公寓表的外键
OneToMany:
学生实体:
package model;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table;
@Entity @Table(name="Student2") public class Student2 {
@Id @Column(name="id") private int id; @Column(name="name") private String name; @Column(name="sex") private String sex;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }} |
公寓实体
package model;
import java.util.List;
import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table;
@Entity @Table(name="Department2") public class Department2 {
@Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private long id;
@Column(name="name") private String name;
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) @JoinColumn(name="Dep_Id") //student表里公寓的外键名称 private List<Student2> student2s;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<Student2> getStudent2s() { return student2s; }
public void setStudent2s(List<Student2> student2s) { this.student2s = student2s; }
} |
测试类
package main;
import java.util.ArrayList; import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;
import model.Department; import model.Department2; import model.Student; import model.Student2;
public class StudentTest { private static final String PERSISTENCE_UNIT_NAME = "EmployeeService"; private static EntityManagerFactory factory;
public static void main(String[] args) { factory = Persistence.createEntityManagerFactory( PERSISTENCE_UNIT_NAME); EntityManager em = factory.createEntityManager(); //保证事务 em.getTransaction().begin();
/*Student student =new Student(); student.setName("David"); student.setSex("女");
Department department =new Department(); department.setName("孔子学院学生公寓");
student.setDepartment(department); */ Student2 student2 =new Student2(); student2.setName("David"); student2.setSex("女"); List<Student2> list =new ArrayList<>(); list.add(student2);
Department2 department2 =new Department2(); department2.setName("孔子学院学生公寓"); department2.setStudent2s(list);
em.persist(department2); //因为在department2的实体中设置了student2的cascade //注解属性所以直接保存department2就可以同时保存student2 em.getTransaction().commit(); em.close(); } } |
运行结果
四张图片对比,发现不论是用manyToOne注解还是OneToMany注解,最后生成的表示一样的。