多表操作
多表之间的关系和操作多表的操作步骤
表关系
- 一对多
- 一对多 >> 一:主表 多:从表
- 多对多 >> 中间表中最少应该由两个字段组成,这两个字段作为外键指向两张表的主键,又组成了联合主键
分析步骤
- 明确表关系
- 确定表关系( 描述: 外键 | 中间表 )
- 编写实体类,在实体类中描述表关系(包含关系)
- 配置映射关系
完成多表操作
一对多操作 案例:客户和联系人(一对多关系)
>> 客户:一家公司 联系人:这家公司的员工
一个客户可以具有多个联系人,一个联系人从属于一家公司
分析步骤
1. 明确表关系 >> 一对多关系
2. 确定表关系,再从表上添加外键(描述: 外键 I 中间表)
- 主表:客户表
- 从表:联系人表
3. 编写实体类,在实体类中描述表关系(包含关系)
- 客户:在客户的实体类中包含一个联系人的集合
- 联系人:在联系人的实体类中包含一个客户的对象
4. 配置映射关系
使用JPA注解配置一对多映射关系
操作步骤
1.引入依赖坐标,导入实体类和xml文件
2. Customer >> 配置客户和联系人之间的一对多关系
1 @OneToMany(targetEntity = LinkMan.class) //对方实体类的字节码对象
2 @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id") //name:外键的名称 referencedColumnName: 外键的取值来源
3 private Set<LinkMan> linkMans = new HashSet<LinkMan>();
LinkMan >> 配置客户和联系人之间的一对多关系
1 @ManyToOne(targetEntity = Customer.class)
2 @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
3 private Customer customer;
配置外键的过程中,配置到多的一方,就会在多的一方维护外键
3. 保存一个客户,保存一个联系人
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration(locations = "classpath:applicationContext.xml") 3 public class OneToManyTest { 4 @Autowired 5 private CustomerDao customerDao; 6 @Autowired 7 private LinkManDao linkManDao; 8 /** 9 * 保存一个客户,保存一个联系人 10 * 效果:客户和联系人作为独立的数据保存到数据库中 11 * 联系人的外键为空 12 * 原因? >> 实体类中没有配置关系!! 14 */ 15 @Test 16 @Transactional //配置事务 17 @Rollback(false) //不自动回滚 18 public void testAdd() { 19 //创建一个客户,创建一个联系人 20 Customer customer = new Customer(); 21 customer.setCustname("百度"); 22 23 LinkMan linkMan = new LinkMan(); 24 linkMan.setLkmName("小李"); 25 /** 26 * 配置了客户到联系人的关系 27 * 从客户的角度上:发送两条insert语句,发送一条更新语句更新数据库(更新外键) 28 * 由于我们配置了客户到联系人的关系:客户可以对外键进行维护 29 */ 30 customer.getLinkMans().add(linkMan); 31 32 customerDao.save(customer); 33 linkManDao.save(linkMan); 34 }
进行改进
1 /** 2 * 配置联系人到客户的关系(多对一) 3 * 只发送了两条insert语句 4 * 由于配置了联系人到客户的映射关系(多对一),联系人就能在保存的时候维护外键5 */ 6 linkMan.setCustomer(customer);
再进行改进
1 linkMan.setCustomer(customer);//由于配置了多的一方到一的一方的关联关系(当保存的时候,就已经对外键赋值)
2 customer.getLinkMans().add(linkMan);//由于配置了一的一方到多的一方的关联关系(发送一条update语句)
结果:会有一条多余的update语句 ,是由于一的一方会维护外键,发送update语句
解决的办法:只需要在一的一方放弃维护权即可
1 @OneToMany(mappedBy = "customer")// mappedBy:对方配置关系的属性名称,如下橙色条
2 private Set<LinkMan> linkMans = new HashSet<LinkMan>();对方配置关系的属性名称
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
private Customer customer;