级联操作:指操作一个对象同时操作它的关联对象
在实际开发中,级联删除请慎用!(在一对多的情况下)
多表操作中的一对多:
1.对于数据库中表的建立
外键在《多》的一方进行建立
/*创建客户表*/
CREATE TABLE cst_customer (
...
PRIMARY KEY (`cust_id`)
}
/*创建联系人表*/
CREATE TABLE cst_linkman (
...
PRIMARY KEY (`lkm_id`),
CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
}
2.实体类的操作
其中一:为客户, 多:联系人
外键在《多》的一方进行维护,而在为《一》的一方需要放弃对主键的维护权。
2.1为《一》的客户的实体类添加的注解为:
* 放弃外键维护权
* mappedBy:对方配置关系的属性名称\
* cascade : 配置级联(可以配置到设置多表的映射关系的注解上)
* CascadeType.all : 所有操作
* MERGE :更新
* PERSIST :保存
* REMOVE :删除
*
* fetch : 配置关联对象的加载方式
* EAGER :立即加载
* LAZY :延迟加载
@Table(name="cst_customer")
public class Customer {
...
@OneToMany(mappedBy = "customer",cascade = CascadeType.ALL)
private Set<LinkMan> linkMans = new HashSet<>();
...
}
2.2为《多》的联系人的实体类添加的注解:
@Table(name = "cst_linkman")
public class LinkMan {
...
* 1.配置表关系
* @ManyToOne : 配置多对一关系
* targetEntity:对方的实体类字节码
* 2.配置外键(中间表)
*
* * 配置外键的过程,配置到了多的一方,就会在多的一方维护外键
*配置外键(中间表)
* @JoinColumn : 配置外键
* name:外键字段名称
* referencedColumnName:参照的主表的主键字段名称
*/
@ManyToOne(targetEntity = Customer.class,fetch = FetchType.LAZY)
@JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
private Customer customer;
...
}
3实现逻辑操作
3.1实现CustomerDao接口
public interface CustomerDao extends JpaRepository<Customer,Long> ,JpaSpecificationExecutor<Customer> {
}
实现CustomerDao接口
public interface LinkManDao extends JpaRepository<LinkMan,Long>, JpaSpecificationExecutor<LinkMan> {
}
3.2实现添加操作
@Test
@Transactional //配置事务
@Rollback(false) //不自动回滚
public void testAdd2() {
//创建一个客户,创建一个联系人
Customer customer = new Customer();
customer.setCustName("百度");
LinkMan linkMan = new LinkMan();
linkMan.setLkmName("小李");
linkMan.setCustomer(customer);//由于配置了多的一方到一的一方的关联关系(当保存的时候,就已经对外键赋值)
customer.getLinkMans().add(linkMan);//由于配置了一的一方到多的一方的关联关系(发送一条update语句)
customerDao.save(customer);
linkManDao.save(linkMan);
}
3.3删除操作
@Test
@Transactional //配置事务
@Rollback(false) //不自动回滚
public void testCascadeRemove() {
//1.查询1号客户
Customer customer = customerDao.findOne(1l);
//2.删除1号客户
customerDao.delete(customer);
}
4.对象的导航查询
查询一个对象的同时,通过此对象查询他的关联对象
从一方查询多方
* 默认:使用延迟加载(****)
从多方查询一方
* 默认:使用立即加载
public void testQuery1() {
//查询id为1的客户
Customer customer = customerDao.getOne(1l);
//对象导航查询,此客户下的所有联系人
Set<LinkMan> linkMans = customer.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
}