不论是对于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 (?, ?, ?)
分享到:
相关推荐
本资料包"10_JPA详解_JPA中的一对多双向关联与级联操作.zip"聚焦于JPA中的一个重要概念——一对多双向关联及其级联操作。以下是对这一主题的详细阐述。 **一对多关联** 在关系数据库设计中,一对多关联是最常见的...
级联操作不仅可以应用于删除,还可以应用于其他操作,如`PERSIST`(保存)、`MERGE`(合并)、`REFRESH`(刷新)和`DETACH`(分离)。选择哪种级联类型取决于业务需求,需要注意的是过度使用级联可能会导致不必要的...
3. 级联操作详解:阐述各种级联类型的含义和使用场景,以及如何在实体上设置级联策略。 4. 示例代码解析:提供具体的代码示例,展示如何在实体类中定义关联,并进行增删改查操作。 5. 性能优化建议:讨论如何通过...
例如,`@OneToMany`和`@ManyToOne`用于表示一对多或多对一的关系,级联操作如`CascadeType.PERSIST`、`CascadeType.MERGE`等可以确保当一个实体被保存或更新时,与其关联的实体也会相应更新。这在处理关联数据时非常...
JPA支持懒加载和级联操作,比如在上述用户和订单的例子中,可以通过设置`mappedBy`属性实现懒加载,而级联操作如`CascadeType.ALL`可以在操作用户时同时处理关联的订单。 9. **实体状态管理** JPA定义了四种实体...
- 可以使用`CascadeType`来定义级联操作,如`CascadeType.PERSIST`、`CascadeType.REMOVE`等,以便在保存或删除某个实体时自动处理其关联实体。 4. **自定义查询**: - 除了基本的实体关联映射外,还可以通过编写...
- 要保存或更新Employee,我们可以直接调用`EntityManager`的`persist()`或`merge()`方法,JPA会处理外键的设置。 - 读取Employee时,可以直接访问`department`属性获取对应的Department实例。 4. **懒加载与即时...
1. `ALL`:所有操作都级联,包括`PERSIST`, `MERGE`, `REMOVE`, `REFRESH`和`DETACH`。选择`ALL`意味着关联实体会跟随主实体进行所有操作。 2. `PERSIST`:当对一个实体执行`persist()`操作时,关联实体也会被持久...
例如,如果我们设置了`cascade = CascadeType.PERSIST`,当父实体被保存时,与其关联的所有子实体也会被保存。同样,`CascadeType.REMOVE`会确保删除父实体时,所有相关联的子实体也被删除。在你提供的文件名`JPA-...
1. **显式保存关联对象:** 可以通过调用`Session.save()`或`Session.persist()`方法显式地保存关联对象。 2. **使用级联操作:** 在实体关联定义中使用`cascade`属性来自动处理这些操作。例如: ```java @...
3. ** Cascade操作**:`@ManyToMany`支持级联操作,如`CascadeType.PERSIST`、`CascadeType.MERGE`等,这使得在保存或更新主侧实体时,关联的次侧实体也会相应处理。 4. **Fetch策略**:默认情况下,JPA使用懒加载...
比如,`CascadeType.ALL`表示所有数据库操作(包括保存、更新、删除等)都会传递到关联的对象。可以根据需求选择合适的行为。 5. **查询与操作关联对象**: - 使用`Session`对象的`load()`或`get()`方法可以直接...
在JPA中,一对多关系通过@OneToMany和@ManyToOne注解定义,级联操作如CascadeType.PERSIST、CascadeType.REMOVE允许在操作父对象时自动处理子对象的状态。 **11. JPA中的一对多延迟加载与关系维护(一对多关系:二...
JPA的`CascadeType`可以设置为不同的值,比如`PERSIST`, `MERGE`, `REMOVE`等,以控制关联实体的生命周期。例如,如果希望当删除学生时,自动删除所有关联的课程,可以在`@ManyToMany`上添加`cascade = CascadeType....
- `CascadeType.PERSIST`: 级联创建操作。 - `CascadeType.MERGE`: 级联合并操作。 - `CascadeType.REMOVE`: 级联删除操作。 - `CascadeType.REFRESH`: 级联刷新操作。 - `CascadeType.ALL`: 所有上述操作。 #### ...
### JAVA -- JPA注解详解 #### 1. @Entity 注解 - **定义**:`@Entity` 是 Java Persistence API (JPA) 中用于标识一个类作为持久化实体类的关键注解。它告诉 JPA 提供商(如 Hibernate)这个类将会映射到数据库表...
这些关联可以通过注解来定义,并且可以配置级联操作(如CascadeType.ALL),以简化数据操作。 查询方面,除了JPQL,Hibernate还提供了 Criteria 查询,这是一种更加面向对象的查询方式,允许使用API构建查询条件,...
常见的级联类型有:`CascadeType.ALL`、`CascadeType.PERSIST`、`CascadeType.MERGE`等。 6. **HQL与Criteria查询** HQL是Hibernate特有的面向对象的查询语言,类似于SQL,但更接近Java语法。Criteria查询则是通过...
`@PersistenceContext`注解用于注入`EntityManager`实例,它是JPA的核心接口之一,用于执行CRUD操作。 **示例:** ```java @Stateless public class UserService { @PersistenceContext private EntityManager em...
- 使用`cascade`属性,可以配置级联操作,如`CascadeType.PERSIST`会使得在保存用户时同时保存所有关联的订单。 6. **集合类型的选择**: - `OneToMany`关系通常与`List`, `Set`等集合类型一起使用。选择哪种类型...