最近得到了如下需求:公司新增部门的时候,可以选择上级部门,此时这个公司下所有的部门信息可以以树形结构返回给前端,类似于下图(网上找的一张)。
集成开发环境:Java JDK 1.8,Mybatis,SQL server,IDEA。
数据库表结构的设计:部门信息为一张表,id为自增主键;companyId为公司的ID(可以联想到还有一张公司表,这里不展示公司信息表);parentId为上级部门ID,parentID为0的时候,表示没有上级部门;name为部门名称;description为部门描述;deleted表示此数据是否可用(0可用,1已删除)。
数据库表中数据如下:
由数据库我们可以得到如下的部门树结构(此处部门结构只为测试使用,不符合真正的公司部门结构):
技术部
项目管理部
产品部
开发部
网站开发部
App研发部
财务部
会计部
出纳部
人力资源部
招聘部
薪酬绩效部
这个树结构我们可以使用递归来实现,这里主要的递归实现如下(此段代码以下为详细实现,可以不看)。主要是用递归的思想来查询下级部门信息:
@Test
public void test01() throws IOException{
Department department = new Department();
department.setCompanyId(12L);
department.setParentId(0L);
List departmentTrees = getDepartment(department);
}
//递归获取下级部门信息
private List getDepartment(Department department) {
List departmentTrees = mapper.getDepartmentTree(department);
if (departmentTrees.size() > 0) {
Department sonDepartment = new Department();
for (int i = 0; i < departmentTrees.size(); i++) {
sonDepartment.setParentId(departmentTrees.get(i).getId());
sonDepartment.setCompanyId(department.getCompanyId());
List sonDepartmentTree = getDepartment(sonDepartment);
departmentTrees.get(i).setDepartmentTrees(sonDepartmentTree);
}
}
return departmentTrees;
}
工程详细代码实现如下(可以不看):
mybatis配置文件mybatis-config.xml:
数据库连接信息配置文件jdbcconfig.properties:
jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.16.6.98:1433;DatabaseName=mybatis
jdbc.username=sa
jdbc.password=sa123456
mybatis的SQL实现配置文件DepartmentMapper.xml:
实体类:
public class Department {
//部门ID
private Long id;
//公司ID
private Long companyId;
//上级部门ID
private Long parentId;
//部门名称
private String name;
//部门描述
private String description;
//是否删除
private boolean deleted;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
@Override
public String toString() {
return "Department{" +
"id=" + id +
", companyId=" + companyId +
", parentId=" + parentId +
", name='" + name + '\'' +
", description='" + description + '\'' +
", deleted=" + deleted +
'}';
}
}
public class DepartmentTree {
/**
* 部门ID
*/
private Long id;
/**
* 部门名称
*/
private String name;
/**
* 部门信息树
*/
private List departmentTrees;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getDepartmentTrees() {
return departmentTrees;
}
public void setDepartmentTrees(List departmentTrees) {
this.departmentTrees = departmentTrees;
}
@Override
public String toString() {
return "DepartmentTree{" +
"id=" + id +
", name='" + name + '\'' +
", departmentTrees=" + departmentTrees +
'}';
}
}
方法的定义DepartmentMapper:
public interface DepartmentMapper {
public List getDepartmentTree(Department department);
}
最后我们的Test类:
public class MyTest {
public MyTest() throws IOException {
}
public SqlSessionFactory getSqlSessionFactory() throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
SqlSession openSession = getSqlSessionFactory().openSession();
DepartmentMapper mapper = openSession.getMapper(DepartmentMapper.class);
@Test
public void test01() throws IOException{
Department department = new Department();
department.setCompanyId(12L);
department.setParentId(0L);
List departmentTrees = getDepartment(department);
System.out.println("获得的部门信息树为:" + departmentTrees.toString());
}
//递归获取下级部门信息
private List getDepartment(Department department) {
List departmentTrees = mapper.getDepartmentTree(department);
if (departmentTrees.size() > 0) {
Department sonDepartment = new Department();
for (int i = 0; i < departmentTrees.size(); i++) {
sonDepartment.setParentId(departmentTrees.get(i).getId());
sonDepartment.setCompanyId(department.getCompanyId());
List sonDepartmentTree = getDepartment(sonDepartment);
departmentTrees.get(i).setDepartmentTrees(sonDepartmentTree);
}
}
return departmentTrees;
}
}
执行结果如下:
然后打印出的信息树如下:
[
DepartmentTree{
id=1,
name='技术部',
departmentTrees=[
DepartmentTree{
id=2,
name='项目管理部',
departmentTrees=[
]
},
DepartmentTree{
id=3,
name='产品部',
departmentTrees=[
]
},
DepartmentTree{
id=4,
name='开发部',
departmentTrees=[
DepartmentTree{
id=5,
name='网站研发部',
departmentTrees=[
]
},
DepartmentTree{
id=6,
name='App研发部',
departmentTrees=[
]
}
]
}
]
},
DepartmentTree{
id=10004,
name='财务部',
departmentTrees=[
DepartmentTree{
id=10005,
name='会计部',
departmentTrees=[
]
},
DepartmentTree{
id=10006,
name='出纳部',
departmentTrees=[
]
}
]
},
DepartmentTree{
id=10007,
name='人力资源部',
departmentTrees=[
DepartmentTree{
id=10008,
name='招聘部',
departmentTrees=[
]
},
DepartmentTree{
id=10009,
name='薪酬绩效部',
departmentTrees=[
]
}
]
}
]
这样我们就获得了我们需要的部门信息树。这里主要是用递归的思想来实现层级的查询。
项目结构如下: