employee与employee_detail一对一关系SQL创建及JPA映射咨询
关系确认
你描述的「一名员工对应唯一员工详情、一条员工详情对应唯一员工」属于标准的一对一关系,你当前将关联外键放在employee表、以employee为关系维护端的设计逻辑符合常规业务需求,只需要做少量调整即可实现你要的employee_detail_id自动同步效果。
1 SQL语句优化
你原有SQL的基础结构没问题,只需要补充一对一关系的唯一约束、调整外键级联规则,同时建议修改字符集支持中文:
USE `etsystem`; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `employee_detail`; CREATE TABLE `employee_detail` ( `id` int(11) NOT NULL AUTO_INCREMENT, `work_experience` int(11) DEFAULT NULL, `hobby` varchar(45) DEFAULT NULL, `nationality` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; DROP TABLE IF EXISTS `employee`; CREATE TABLE `employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `first_name` varchar(45) DEFAULT NULL, `last_name` varchar(45) DEFAULT NULL, `email` varchar(45) DEFAULT NULL, `employee_detail_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_EMP_DETAIL` (`employee_detail_id`), -- 加唯一约束,避免同一条详情绑定多个员工 CONSTRAINT `FK_DETAIL` FOREIGN KEY (`employee_detail_id`) REFERENCES `employee_detail` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -- 级联操作保证数据同步 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; SET FOREIGN_KEY_CHECKS = 1;
2 Java实体映射调整
你原有注解配置基本可用,只需要补充双向关联维护逻辑,即可实现employee_detail_id自动赋值:
Employee 实体(关系维护端)
// 已省略@Entity、@Table、主键id等基础配置 @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "employee_detail_id", unique = true) private EmployeeDetail employeeDetail; // 关联绑定工具方法,主动维护双向关系 public void bindDetail(EmployeeDetail detail) { this.employeeDetail = detail; detail.setEmployee(this); }
EmployeeDetail 实体(关系被维护端)
// 已省略@Entity、@Table、主键id等基础配置 @OneToOne(mappedBy = "employeeDetail", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) private Employee employee;
3 操作示例
保存数据时调用绑定方法即可,JPA会自动级联保存详情、同步employee_detail_id字段值,无需手动赋值:
// 创建对象 Employee employee = new Employee(); employee.setFirstName("明"); employee.setLastName("李"); employee.setEmail("liming@test.com"); EmployeeDetail detail = new EmployeeDetail(); detail.setWorkExperience(5); detail.setHobby("登山"); detail.setNationality("中国"); // 绑定关联 employee.bindDetail(detail); // 直接保存员工即可,自动完成级联保存和字段同步 employeeDao.save(employee);
执行后可直接验证数据库,employee表的employee_detail_id和employee_detail表对应记录的id完全一致。
内容的提问来源于stack exchange,提问作者Stefan Jankovic
相关产品推荐
相关产品推荐

