In recent projects, we often encounter the need to store parent-child relationships in the database, and then obtain the tree structure objects to be generated according to the ParentId.
I don't know whether my brain is bad or something recently. It po took me a long time to figure out how to build the structure. After 55555 finally knocked out, it suddenly became clear that they all had the impulse to cry.
Without much nonsense, I began to summarize and share my problem-solving ideas. (actually, it's not difficult. I'm a vegetable chicken)
demand
-
There is a table with the following structure in the database:
-
We need to get the data from the database and parse it into the following tree format:
Problem solving ideas
-
Let's compare it like a thing. Well, old habits, everything comes from life. It's often easier to understand by looking for examples from life.
This question is actually equivalent to:
There is a family, tell you who everyone's father is, and then let you make their family spectrum.
Isn't that what happened!!!!! -
So let's think about the genealogy. How should we accomplish this? I think first of all, we can line up everyone's list first. As shown below:
-
Then look at the information provided to us. We can know who everyone's father is. Then add whoever dad is. As shown below:
-
Finally, we will get the result shown in the figure below. What do we know at this time? Careful observation shows that we know which sons each father has. From who everyone's father is to how many sons everyone has. This step is crucial. I haven't figured out how to solve the problem. It's stuck at this point.
-
So why know who everyone's son is? Because that's what we're going to do next. First, we call the oldest object 1, then ask him to call his son, and then son object 2 calls his son. Finally, the following figure is obtained.
code implementation
The above nonsense is a pile, but in fact, as long as you understand the above logic. The code is easy to write.
- First, create a User class to match the data structure of the database to obtain data.
@Data @AllArgsConstructor @NoArgsConstructor public class User{ private Integer id; private String name; private Integer parentId; }
- First, create a UserVO class as the final data structure of the output.
@Data @AllArgsConstructor @NoArgsConstructor public class UserVO{ private Integer id; private String name; private List<UserVO> children; }
- First, get all users from the database
... List<User> userList = UserMapper.getAllUser(); ...
- Create a HashMap, traverse the collection in the previous step, convert the User into UserVO, and assign a value to the HashMap. key is parentid and value is the subclass UserVO object. Another is to create a UserVO collection to store the transformed UserVO. After all, after the transformation, you don't have to look at the User.
... List<User> userList = UserMapper.getAllUser(); Map<Integer,List<UserVO>> parentIdUserVOMap = new HashMap<>(); List<UserVO> userVOList = new ArrayList<>(); for(User user : userList){ UserVO userVO = new UserVO(); BeanUtils.copyProperities(user,userVO); userVOList.add(userVO); int parentId = user.getParentId(); if(parentIdUserVOMap.containsKey(parentId)){ List<UserVO> userVOs = parentIdUserVOMap.get(parentId); userVOs.add(userVO); }else{ List<UserVO> userVOs = new ArrayList<>(); userVOs.add(userVO); parentIdUserVOMap.put(parentId,userVOs); } } ...
- At this time, we know all the fathers and their sons. But the sons haven't followed their father yet. That is, at present, the children attribute of each UserVO is empty. We need to put subclasses in. How? Go through all the dads again and let them take their sons.
... for(UserVO userVO : userVOList){ List<UserVO> childs = parentIdUserVOMap.get(userVO.getId()); userVO.setChildren(childs); } ...
- The last step is to get the oldest father as the top of the tree structure, that is, this person has no father recorded, parentId==0
... List<UserVO> result = parentIdUserVOMap.get(0); ...
summary
Well, this po problem is solved. Before I figured it out, I really walked around for a long time and couldn't figure out why the database should design tables so much. After the connection, everything seemed reasonable. I don't know. Do you understand? If you think it's good, remember to pay attention to it with one button three times! If you have better design ideas or solutions, you can also leave a message below. I'm a vegetable dog. I hope the big guys will take me!!!