本次实验环境:spring boot + spring data jpa + hibernate
本次实验用例:
人:
id
name
cars
车:
id
nr
person
本次实例展示如何编写一对多双向关系,直接展示常用的编写方式,不再涉及假设讨论。
#Person类:
@Entity
@Table(name="t_12n_person")
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy="person", cascade= {CascadeType.MERGE, CascadeType.REFRESH, CascadeType.REMOVE})
private List<Car> cars;
//getter与setter省略
}
mappedBy设置效果为不在person表里维护关系,person表里没有car的id,也没有中间表来维护关系。如果不写则会自动生成一张中间表。
cascade设置MERGE,REFRESH和REMOVE。主要是REMOVE,如果person删除了,那么该person的所有car都要删除。如果业务逻辑不是这样,那么请在代码里维护该关系,第一步断掉所有相关car与此person的关系,第二步删除该person。不设置REMOVE且上述步骤同一事务。
#Car类:
@Entity
@Table(name="t_12n_car")
public class Car {
@Id
@GeneratedValue
private Long id;
private String nr;
@ManyToOne
@JoinColumn(name="person_id")
private Person person;
//getter与setter省略
}
在car这一方维护关系,设置car的表里的外键字段名为person_id,指向person表的id。
#生成表
CRUD:
- 添加person,直接添加即可。
Person person = new Person();
person.setName("张三");
personDao.saveAndFlush(person); - 更新person,先查出原有数据再更新。
Person person = personDao.findOne(1L);
person.setName("李四");
personDao.saveAndFlush(person); - 删除person,级联删除car。
personDao.delete(1L);
查询person,@OneToMany默认为懒加载。
Person person = personDao.findOne(1L);
System.err.println(person.getName());添加car,查出person,设置关系,直接添加。
Car car = new Car();
car.setNr("牌照一");
car.setPerson(personDao.findOne(1L));
carDao.saveAndFlush(car);- 更新car,先查出原有数据再更新。
Car car = carDao.findOne(1L);
car.setNr("超级牌照一");
carDao.saveAndFlush(car); - 删除car,直接通过id删除即可。
carDao.delete(2L);
- 查询car,@ManyToOne默认急加载。
Car car = carDao.findOne(1L);
System.err.println(car);
不管是添加关系还是断掉关系,全有carDao来执行,personDao只需维护person自身的字段。