双向一对多的建表
++需要注意:主键要使用JPA策略生成, 不然使用级联操作的时候回多出几条查询语句,增加应用和数据库交互的负担。++
t_category 为One的一方,t_fruit为多的一方
# 类型表
create table t_category
(
id varchar(64) not null
primary key,
name varchar(50) null
)
charset = utf8;
# 水果表
create table t_fruit
(
id varchar(64) not null
primary key,
name varchar(50) null,
category_id varchar(64) null,
constraint fk_t_fruit_id
foreign key (category_id) references t_category (id)
)
charset = utf8;
2、实体映射
Many的一方映射如下:
@Entity
@Table(name = "t_fruit")
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Fruit {
@Id
@GeneratedValue(generator = "uid")
@GenericGenerator(name = "uid", strategy = "uuid")
private String id;
private String name;
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.PERSIST)
// 双向一对多,外键必须配置为一样的值
@JoinColumn(name = "category_id")
private Category category;
public Fruit(String id, String name){
this.id = id;
this.name = name;
}
}
One的一方实体如下:
mappedBy: 参照many一方的外键管理来实现关系关联
@Entity
@Table(name = "t_category")
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Category {
@Id
@GeneratedValue(generator = "uid")
@GenericGenerator(name = "uid", strategy = "uuid")
private String id;
private String name;
// 单向一对多: 一个水果类型对应多种水果
@OneToMany(fetch = FetchType.LAZY, mappedBy = "category",cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Fruit> fruits = new ArrayList<>();
public Category(String id, String name){
this.id = id;
this.name = name;
}
3、实现级联保存
实现级联保存的前提条件:
a、必须两边都要建立关系
b、在映射上添加 cascade = CascadeType.PERSIST
/**
*
* 实现级联保存条件:
* 1、必须两边都建立关系
* 2、关联上配置: cascade = CascadeType.PERSIST,mappedBy = "category"
*/
@Test
public void persistenceTest(){
// one
Category category = new Category();
category.setName("fruit");
// many
Fruit fruit1 = new Fruit();
fruit1.setName("西瓜");
Fruit fruit2 = new Fruit();
fruit2.setName("苹果");
// relative
category.getFruits().add(fruit1);
category.getFruits().add(fruit2);
fruit1.setCategory(category);
fruit2.setCategory(category);
// persistence
categoryRepository.save(category);
}
级联删除
在实体上配置映射cascade = {CascadeType.REMOVE})
/**
*
* 实现级联删除
* 删除一方, 然后级联删除多方
*
*/
@Test
public void persistenceDeleteTest(){
Category category = categoryRepository.getOne("40289f1f704e74ca01704e74dd910000");
categoryRepository.delete(category);
}