1. 概述
上一篇介绍了Spring Data JPA单表基本操作,在实际开发中,经常会涉及到多表关联查询,本文主要介绍SpringBoot如何整合Spring Data JPA来实现复杂的多表关联查询。pom核心依赖和yml配置信息见SpringBoot2.3整合Spring Data JPA实现基本操作
2. 表和数据准备
首先新建几张表,sql如下:
CREATE TABLE address_info (
id BIGINT UNSIGNED auto_increment NOT NULL COMMENT '主键ID',
province varchar(20) NULL COMMENT '省',
city varchar(20) NULL COMMENT '市',
area varchar(20) NULL COMMENT '区',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间',
CONSTRAINT address_info_pk PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='地址信息表';
CREATE TABLE dept_info (
id BIGINT UNSIGNED auto_increment NOT NULL COMMENT '主键ID',
dept_name varchar(30) NULL COMMENT '部门名称',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间',
CONSTRAINT dept_info_pk PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='部门表';
CREATE TABLE salary_info (
id BIGINT UNSIGNED auto_increment NOT NULL COMMENT '主键ID',
emp_id BIGINT UNSIGNED NULL COMMENT '用户ID',
salary_year INT NULL COMMENT '年份',
salary_month TINYINT NULL COMMENT '月份',
salary DECIMAL NULL COMMENT '薪水',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间',
CONSTRAINT salary_info_pk PRIMARY KEY (id),
CONSTRAINT emp_id_FK FOREIGN KEY (emp_id) REFERENCES emp_info(id) ON DELETE RESTRICT ON UPDATE RESTRICT
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='薪水表';
CREATE TABLE emp_info (
id BIGINT UNSIGNED auto_increment NOT NULL COMMENT '主键ID',
emp_name varchar(30) NULL COMMENT '员工姓名',
phone varchar(11) NULL COMMENT '手机号',
dept_id BIGINT UNSIGNED NULL COMMENT '部门编号',
addr_id BIGINT UNSIGNED NULL COMMENT '地址ID',
create_time DATETIME NULL COMMENT '创建时间',
update_time DATETIME NULL COMMENT '更新时间',
CONSTRAINT emp_info_pk PRIMARY KEY (id),
CONSTRAINT dept_id_FK FOREIGN KEY (dept_id) REFERENCES dept_info(id) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT address_id_FK FOREIGN KEY (addr_id) REFERENCES address_info(id) ON DELETE RESTRICT ON UPDATE RESTRICT
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='员工表';
3. 核心实体类
@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Table(name = "emp_info")
public class EmpInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String empName;
private String phone;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "dept_id")
private DeptInfo deptInfo;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "addr_id")
private AddressInfo addressInfo;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@OrderBy("id")
@BatchSize(size = 12)
@OneToMany(mappedBy = "empInfo", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<SalaryInfo> salaryInfos;
}
解释:FetchType用于配置获取数据策略,EAGER表示及时加载数据,LAZY表示使用的时候才加载数据;CascadeType用于配置多表级联操作,PERSIST表示给当前实体类操作另一个实体类的权限,MERGE表示当前实体类数据改变时,会相应更新映射实体类数据,REMOVE表示删除当前实体类数据时,会相应删除映射实体类数据,REFRESH表示操作数据前先刷新数据再做操作,DETACH表示删除当前实体类数据时,撤销映射实体类外键关联,ALL表示拥有所有权限。
4. 业务接口
public interface EmpService {
/**
* 保存数据
* @param empInfo
* @return
*/
EmpInfo insertEmpInfo(EmpInfo empInfo);
/**
* 更新数据
* @param empInfo
* @return
*/
EmpInfo updateEmpInfo(EmpInfo empInfo);
/**
* 根据主键ID查询数据
* @param id
* @return
*/
EmpInfo findById(Long id);
/**
* 分页查询
* @param pageNum
* @param pageSize
* @return
*/
Page<EmpInfo> findByPage(int pageNum, int pageSize);
/**
* 多条件分页查询
* @param empName
* @param pageNum
* @param pageSize
* @return
*/
Page<EmpInfo> findByExampleAndPage(String empName, int pageNum, int pageSize);
}
5. 业务接口实现类
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpRepository empRepository;
@Override
public EmpInfo insertEmpInfo(EmpInfo empInfo) {
return empRepository.save(empInfo);
}
@Override
public EmpInfo updateEmpInfo(EmpInfo empInfo) {
return empRepository.save(empInfo);
}
@Override
public EmpInfo findById(Long id) {
return empRepository.findById(id).get();
}
@Override
public Page<EmpInfo> findByPage(int pageNum, int pageSize) {
Pageable pageable = PageRequest.of(pageNum, pageSize);
return empRepository.findAll(pageable);
}
@Override
public Page<EmpInfo> findByExampleAndPage(String empName, int pageNum, int pageSize) {
EmpInfo empInfo = new EmpInfo();
empInfo.setEmpName(empName);
Pageable pageable = PageRequest.of(pageNum, pageSize);
ExampleMatcher exampleMatcher = ExampleMatcher.matching()
.withMatcher("empName", ExampleMatcher.GenericPropertyMatchers.exact());
Example<EmpInfo> example = Example.of(empInfo, exampleMatcher);
return empRepository.findAll(example, pageable);
}
}
6. 映射注解说明
@OneToMany
用于建立一对多关系映射
属性:
- targetEntityClass:指定多对多方的类的字节码
- mappedBy:指定从表书体类中引用主表对象的名称
- cascade:指定要使用的级联操作
- fetch:指定是否采用延迟加载
- orphanRemoval:是否使用孤儿删除
@ManyToOne
用于建立一对一关系映射
属性:
- targetEntityClass:指定一对一方的类的字节码
- cascade:指定要使用的级联操作
- fetch:指定是否采用延迟加载
- optional:关联是否可选,如果设置为false,则必须始终存在非空关系
@JoinColumn
用于定义主键字段和外键字段的对应关系
属性:
- name:指定外键字段的名称
- referencedColumnName:指定引用主表的主键字段名称
- unique:是否唯一,默认值不唯一
- nullable:是否允许为空。默认值允许
- insertable:是否允许插入,默认值允许
- updatable:是否允许更新,默认值允许
- columnDefinition:列的定义信息
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/76789.html