欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

jpa级联操作详解1-级联保存(CascadeType.PERSIST)

程序员文章站 2022-05-01 23:15:20
...

不论是对于jpa或者是hibernate来说字段的数据库映射都不是难点,而是很多初学者都对jpa级联操作等一系列的东西不大明白,在这一系列的文章中我通过简单的java实体对象来与大家共同理解jpa(hibernate做实现产品)的级联操作等难点知识,希望能够共同提高。为了保证简单易懂,本系列文章避免光讲理论知识,而忽视实际动手,在下面的例子中都有简单易懂的例子,为了加深理解大家也可以在自己的机器上调试。同时为了方便理解本系列文章采用对比讲解,能让人一目了然。同时欢迎大家共同探讨,一起完善这教程

jpa级联操作详解1(cascade) 之 cascade={CascadeType.PERSIST}

onetomany 一对多关联 实体bean:汽车和车库

(一)

package com.hibernate.jpa.bean1;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Auto {

	/**
	 * one to many 一对多关联
	 */
	private Integer autoId;
	private String autotype;
	private String autonum;
	private Garage garage;

	@Id @GeneratedValue
	public Integer getAutoId() {
		return autoId;
	}
	public void setAutoId(Integer autoId) {
		this.autoId = autoId;
	}
	public String getAutotype() {
		return autotype;
	}
	public void setAutotype(String autotype) {
		this.autotype = autotype;
	}
	public String getAutonum() {
		return autonum;
	}
	public void setAutonum(String autonum) {
		this.autonum = autonum;
	}
	@ManyToOne
	@JoinColumn(name="garageid")
	public Garage getGarage() {
		return garage;
	}
	public void setGarage(Garage garage) {
		this.garage = garage;
	}

}
------车库
package com.hibernate.jpa.bean1;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Garage {

	/**
	 * many to one 多对一
	 */
	private Integer gid;
	private String garagenum;
	private Set<Auto> autos = new HashSet<Auto>();
	
	@Id @GeneratedValue
	public Integer getGid() {
		return gid;
	}
	public void setGid(Integer gid) {
		this.gid = gid;
	}
	@Column(length=20)
	public String getGaragenum() {
		return garagenum;
	}
	public void setGaragenum(String garagenum) {
		this.garagenum = garagenum;
	}
	@OneToMany(mappedBy="garage")
	public Set<Auto> getAutos() {
		return autos;
	}
	public void setAutos(Set<Auto> autos) {
		this.autos = autos;
	}
	public void addGarageAuto(Auto auto) {
		auto.setGarage(this);
		this.autos.add(auto);
	}

}
 ---------junit保存方法
	@Test public void save() {
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Garage garage = new Garage();
		garage.setGaragenum("room1");
		
		Auto auto1 = new Auto();
		auto1.setAutonum("bj0000");
		auto1.setAutotype("car");
		
		Auto auto2 = new Auto();
		auto2.setAutonum("bj1231");
		auto2.setAutotype("bus");
		
		garage.addGarageAuto(auto1);
		garage.addGarageAuto(auto2);
		
		em.persist(garage);
		em.getTransaction().commit();
		em.close();
		factory.close();
	}

运行以上save()方法之后,数据库中只对应的表,但是只有garage表中被存入了数据,而auto表中没有被存入数据,仅仅是生成了表而已。

数据库中的表数据:

+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+

 

mysql> select * from auto;
Empty set (0.00 sec)

这儿可以注意到虽然生成了auto数据库表,但是无法存储有关auto的数据,因为没有先保存auto或设置级联保存

观察发出的sql语句:

Hibernate: insert into Garage (garagenum) values (?)

 

 

(二)先保存auto

将junit测试类中的save方法改为

@Test public void save() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();

Garage garage = new Garage();
garage.setGaragenum("room1");

Auto auto1 = new Auto();
auto1.setAutonum("bj0000");
auto1.setAutotype("car");

Auto auto2 = new Auto();
auto2.setAutonum("bj1231");
auto2.setAutotype("bus");

garage.addGarageAuto(auto1);
garage.addGarageAuto(auto2);
em.persist(auto1);
em.persist(auto2);
em.persist(garage);
em.getTransaction().commit();
em.close();
factory.close();
}

观察发出的sql语句:

Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)
Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)
Hibernate: insert into Garage (garagenum) values (?)
Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?
Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?

当然也生成了对应的数据记录,但是对数据库进行了5次操作

 

mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+

 

mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | bj0000 | car | 1 |
| 2 | bj1231 | bus | 1 |
+--------+---------+----------+----------+

-----------------------------------------------------------------------

(三)设置cascade={CascadeType.PERSIST}

当把

@OneToMany(mappedBy="garage")
public Set<Auto> getAutos() {
return autos;
}

改为:

@OneToMany(cascade={CascadeType.PERSIST} ,mappedBy="garage")
public Set<Auto> getAutos() {
return autos;
}

即多添加了一行cascade={CascadeType.PERSIST} 申明级联级联保存

删除前面生成的数据库表garage 和 auto

再次运行save()方法

这是我们看到数据库中都有对应的记录

+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+

 

+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | bj0000 | car | 1 |
| 2 | bj1231 | bus | 1 |
+--------+---------+----------+----------+

观察发出的sql语句:

Hibernate: insert into Garage (garagenum) values (?)
Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)
Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)