JPA学习——2.关系维护
程序员文章站
2022-03-02 15:20:07
...
如何表示实体之间的关系,我们需要使用一对一、一对多、多对一、多对多的注解进行关系维护和声明
1.双向一对一
person类(1)
@Entity
@Table(name = "PERSONS")
public class Person {
private Integer id;
private String name;
private Card card;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JoinColumn(name = "card_id")
@OneToOne
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
}
Card类(1)
@Entity
@Table(name = "CARD")
public class Card {
private Integer id;
private String number;
private Person person;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@OneToOne(mappedBy = "card")
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
测试
public class MyTest {
private EntityManagerFactory entityManagerFactory;
@Before
public void before(){
entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
@After
public void after(){
entityManagerFactory.close();
}
@Test
public void test(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Person person = new Person();
person.setName("张三");
Card card = new Card();
card.setNumber("123");
person.setCard(card);
card.setPerson(person);
entityManager.persist(card);
entityManager.persist(person);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
结果:
先插入card再插入person,对应的DML:
- insert card
- insert person
先插入person 再插入card,对应的DML:
- insert person
- insert card
- update person
2.单向一对多
customer类(1)
@Entity
@Table(name="CUSTOMER")
public class Customer {
private Integer id;
private String name;
private String tele;
private Set<Order> orders;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="tele",length = 13)
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
@JoinColumn(name = "cus_id")
@OneToMany
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
ordner类(n)
@Entity
@Table(name="ORDERS")
public class Order {
private Integer id;
private String content;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
测试
public class MyTest {
private EntityManagerFactory entityManagerFactory;
@Before
public void before(){
entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
@After
public void after(){
entityManagerFactory.close();
}
@Test
public void test(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Customer customer = new Customer();
customer.setName("张三");
customer.setTele("12314568");
Order order1 = new Order();
order1.setContent("AAAA");
Order order2 = new Order();
order2.setContent("BBBB");
Set<Order> orders = new HashSet<>();
orders.add(order1);
orders.add(order2);
customer.setOrders(orders);
entityManager.persist(customer);
entityManager.persist(order1);
entityManager.persist(order2);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
结果:
先插入客户再插入订单,对应的DML:
- insert客户
- insert订单1
- insert订单2
- update订单1
- update订单2
先插入订单再插入客户,对应的DML:
- insert订单1
- insert订单2
- insert客户
- update订单1
- update订单2
如果设置了级联会先插入客户
3.单向多对一
customer类(1)
@Entity
@Table(name="CUSTOMER")
public class Customer {
private Integer id;
private String name;
private String tele;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="tele",length = 13)
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
}
ordner类(n)
@Entity
@Table(name="ORDERS")
public class Order {
private Integer id;
private String content;
private Customer customer;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
//定义外键列名
@JoinColumn(name = "cus_id")
@ManyToOne
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
测试
public class MyTest {
private EntityManagerFactory entityManagerFactory;
@Before
public void before(){
entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
@After
public void after(){
entityManagerFactory.close();
}
@Test
public void test(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Customer customer = new Customer();
customer.setName("张三");
customer.setTele("12314568");
Order order1 = new Order();
order1.setContent("AAAA");
order1.setCustomer(customer);
Order order2 = new Order();
order2.setContent("BBBB");
order2.setCustomer(customer);
entityManager.persist(order1);
entityManager.persist(order2);
entityManager.persist(customer);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
结果:
先插入客户再插入订单,对应的DML:
- insert客户
- insert订单1
- insert订单2
先插入订单再插入客户,对应的DML:
- insert订单1
- insert订单2
- insert客户
- update订单1
- update订单2
如果设置了级联会先插入客户
3.双向一对多
customer类(1)
@Entity
@Table(name="CUSTOMER")
public class Customer {
private Integer id;
private String name;
private String tele;
private Set<Order> orders;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="tele",length = 13)
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
@JoinColumn(name = "cus_id")
@OneToMany(cascade = CascadeType.ALL)
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
ordner类(n)
@Entity
@Table(name="ORDERS")
public class Order {
private Integer id;
private String content;
private Customer customer;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
//定义外键列名
@JoinColumn(name = "cus_id")
@ManyToOne
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
测试
public class MyTest {
private EntityManagerFactory entityManagerFactory;
@Before
public void before(){
entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
@After
public void after(){
entityManagerFactory.close();
}
@Test
public void test(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Customer customer = new Customer();
customer.setName("张三");
customer.setTele("12314568");
Order order1 = new Order();
order1.setContent("AAAA");
Order order2 = new Order();
order2.setContent("BBBB");
Set<Order> orders = new HashSet<>();
orders.add(order1);
orders.add(order2);
customer.setOrders(orders);
entityManager.persist(customer);
entityManager.persist(order1);
entityManager.persist(order2);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
结果:
先插入客户再插入订单,对应的DML:
- insert客户
- insert订单1
- insert订单2
- update订单1
- update订单2
先插入订单再插入客户,对应的DML:
- insert订单1
- insert订单2
- insert客户
- update订单1
- update订单2
- update订单1
- update订单2
相比较单向多对一的客户先插,双向维护外键无论谁先插都造成多余的update语句,所以我们如果希望使用双向关联同时又可以避免不必要的sql语句,则可以让客户放弃外键维护(@OneToMany(mappedBy = "customer",同时,删除客户的@JoinColumn(name = "cus_id"),否则会造成异常)
客户放弃外键维护后
结果:
先插入客户再插入订单,对应的DML:
- insert客户
- insert订单1
- insert订单2
先插入订单再插入客户,对应的DML:
- insert订单1
- insert订单2
- insert客户
- update订单1
- update订单2
补充:
- 如果不在客户一方加入@JoinColumn(name = "cus_id"),会生成一张中间表
- 如果不在订单一方加入@JoinColumn(name = "cus_id"),订单表会根据类中的变量命生成一个外键列customer_id。然后由于客户一端设置了@JoinColumn(name = "cus_id"),orders表中会出现两个外键
- 如果两边都不加@JoinColumn(name = "cus_id"),订单表会根据类中的变量命生成一个外键列customer_id,而客户一方会由于没有指定外键列,则默认生成一张中间表
4.多对多
student类(n)
@Entity
@Table(name="STUDENT")
public class Student {
private Integer id;
private String name;
private Set<Subject> subjects;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//定义中间表
@JoinTable(
//中间表名
name = "student_subject",
//外键引用
joinColumns = {@JoinColumn(name = "stu_id",referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "sub_id",referencedColumnName = "id")})
@ManyToMany
public Set<Subject> getSubjects() {
return subjects;
}
public void setSubjects(Set<Subject> subjects) {
this.subjects = subjects;
}
}
subject类(m)
@Entity
@Table(name="SUBJECT")
public class Subject {
private Integer id;
private String className;
private Set<Student> students;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
@ManyToMany(mappedBy = "subjects")
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
测试
public class MyTest {
private EntityManagerFactory entityManagerFactory;
@Before
public void before(){
entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
@After
public void after(){
entityManagerFactory.close();
}
@Test
public void test(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Student student1 = new Student();
student1.setName("张三");
Student student2 = new Student();
student1.setName("李四");
Set<Student> students = new HashSet<>();
students.add(student1);
students.add(student2);
Subject subject1 = new Subject();
subject1.setClassName("math");
Subject subject2 = new Subject();
subject2.setClassName("Chinese");
Set<Subject> subjects = new HashSet<>();
subjects.add(subject1);
subjects.add(subject2);
student1.setSubjects(subjects);
student2.setSubjects(subjects);
subject1.setStudents(students);
subject2.setStudents(students);
entityManager.persist(student1);
entityManager.persist(student2);
entityManager.persist(subject1);
entityManager.persist(subject2);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
上一篇: 框架搭建
下一篇: 使用G2的BizChar 踩过的坑