Java

[Java] DB에서 Select 해온 Row에 새로운 List 추가하기

빡새 2022. 9. 19. 09:35

//mapper

<select id="getCategoryList" resultType="HashMap">
    SELECT
        A.seq
        , A.category_code
        , A.category_name
        , A.parent_category_code
    FROM
    	table_category A
    WHERE 
        A.category_code = COALESCE(#{cateCode}, '0002')
        AND A.parent_category_code = #{parentCategoryCode}
</select>


- 원하는 기능 : 하위 카테고리 리스트를 상위 카테고리 -

카테고리 간의 상하 관계를 저장하고 있는 카테고리 테이블이 있다.
대분류, 중분류, 소분류로 총 세 가지 뎁스가 있다.
대분류는 중분류를 포함할 수도 있고, 속해 있는 중분류가 없을 수도 있다.
중분류는 소분류를 포함할 수도 있고, 속해 있는 소분류가 없을 수도 있다.

이러한 상황에서 내가 만들고 싶은 기능은 아래와 같다.
일단 대분류 리스트를 쭉 뽑아 온다.
대분류 안에 속해 있는 중분류가 있다면 그 중분류 리스트를 쭉 뽑아서 'subCategoryList' 라는 이름으로 대분류에 넣어준다.
넣어주는 중분류 리스트 중에서 소분류가 속해 있다면 그 소분류 리스트를 쭉 뽑아서 'subCategoryList'라는 이름으로 중분류 안에 넣어준다.
말하자면 마인드맵이나 피라미드 같은 구조로 데이터를 넣고 싶다.
예를 들면 아래와 같은 구조가 될 것이다.
[   

     대분류1,

     대분류2,

     대분류3:[중분류1],

     대분류4:[중분류2],

     대분류5:[중분류3 , 중분류4, 중분류5],

     대분류6:[중분류6: [소분류1, 소분류2, 소분류3], 중분류7, 중분류8: [소분류4, 소분류5, 소분류6, 소분류7]]

]


- 상위 카테고리 코드를 이용해서 하위 카테고리 리스트 받아오기 -

// Java

param.put("parentCategoryCode", "0000"); // 대분류는 상위 카테고리가 없으므로 상위 카테고리 코드가 "0000"이다. 
List<Map<String, Object>> categoryList1 = this.categoryService.getCategoryList(param); // 대분류를 모두 불러오기 위해서 'parentCategoryCode' 값이 '0000'인 데이터를 모두 뽑아 온다.
if(!CollectionUtils.isEmpty(categoryList1)) {	// 대분류 리스트가 비어 있지 않다면, 즉 안에 내용물이 있다면
	for(Map<String, Object> row1 : categoryList1) {	// 대분류에서 row 하나를 하나씩 꺼내 와서
		if(!ObjectUtils.isEmpty(row1)) {	// 대분류 row 가 비어 있지 않다면, 즉 안에 내용물이 있다면
			param.put("parentCategoryCode", row1.get("categoryCode"));	// 그 대분류에 속해 있는 중분류를 모두 불러오기 위해서 
			List<Map<String, Object>> categoryList2 = this.categoryService.getCategoryList(param); // 그 대분류를 부모 카테고리로 참조하고 있는 데이터를 모두 꺼내 오기
			for(Map<String, Object> row2 : categoryList2) {	// 대분류 안에 속해 있는 중분류 리스트를 모두 받아 왔다면 다시 그 중분류로부터 row를 하나씩 꺼내 와서
				if(!ObjectUtils.isEmpty(row2)) {	// 그 row가 비어 있지 않다면, 즉 안에 내용물이 있다면
					param.put("parentCategoryCode", row2.get("categoryCode")); 	// 대분류 안에 속해 있는 중분류 안에 속해 있는 소분류를 모두 불러오기 위해서 
					List<Map<String, Object>> categoryList3 = this.categoryService.getCategoryList(param);	// 중분류를 부모 카테고리로 참조 하고 있는 데이터를 모두 꺼내 오기
					row2.put("subCategoryList", categoryList3);	// 대분류 안에 속해 있는 중분류 row 하나에 방금 꺼내온 소분류 리스트를 subCategoryList라는 이름으로 넣어 주고
				}
			}
			row1.put("subCategoryList", categoryList2);	// 대분류 row 하나에 방금 꺼내온 중분류 리스트를 subCategoryList라는 이름으로 넣어주기
		}
	}
}

 

 

 


- 구문 하나씩 해석 -

 

List<Map<String, Object>> categoryList1 = this.categoryService.getCategoryList(param);

 

row 하나가 Map<String, Object> 형태이고, 이 row들이 리스트 형태로 담겨 있다.
대분류 리스트는 이런 형태로 이루어져 있을 것이다.
[
{seq: "1", categoryCode: "0001", categoryName: "name1", parentCategoryCode: "0000"},
{seq: "2", categoryCode: "0002", categoryName: "name2", parentCategoryCode: "0000"},
{seq: "3", categoryCode: "0003", categoryName: "name3", parentCategoryCode: "0000"},
{seq: "4", categoryCode: "0004", categoryName: "name4", parentCategoryCode: "0000"},
]


for(Map<String, Object> row1 : categoryList1) { ~~~~ }

 

categoryList1이라는 리스트를 갖고 반복문을 돌려 보자.

그러면 categoryList1이라는 리스트로부터 요소를 하나씩 꺼내서 row1이라는 변수에 담는다.

 


row1은 아래와 같은 Map<String, Object> 형태가 된다.

{seq: "1", categoryCode: "0001", categoryName: "name1", parentCategoryCode: "0000"}



이 row에서 categoryCode 라는 키의 값을 가져오고 싶다.
Map 에서 어떤 값을 꺼낼 때는 get 함수에 key값을 넣어주면 된다.

for(Map<String, Object> row1 : categoryList1) {
	row1.get("categoryCode"); 
}

 


이 대분류를 상위 카테고리로 참조하고 있는 중분류를 모두 가져와야 한다.
그러면 카테고리 테이블에서 상위 카테고리 코드의 값이 이 대분류 코드인 데이터를 모두 뽑아 오면 된다.
따라서 파라미터에 "parentCategoryCode" 이름으로 방금 대분류로부터 꺼내온 카테고리 코드 값을 넣어주자.

for(Map<String, Object> row1 : categoryList1) {
	param.put("parentCategoryCode", row1.get("categoryCode"));
}



그리고 이 파라미터를 가지고 데이터를 뽑아오는 쿼리를 실행하자.

for(Map<String, Object> row1 : categoryList1) {
    param.put("parentCategoryCode", row1.get("categoryCode"));
    List<Map<String, Object>> categoryList2 = this.categoryService.getCategoryList(param); 
}




이 대분류를 상위 카테고리로 참조하고 있는 중분류 리스트가 categoryList2에 담겨 있다.
이 대분류 안에 중분류 리스트를 넣어주자.
현재 대분류 카테고리로부터 row 하나를 꺼내온 상태인데, 그 row는 Map<String, Object> 형태라고 했다.
Map 에 데이터를 넣어줄 때는 put 함수에 key 값과 데이터를 넣어주면 된다.

for(Map<String, Object> row1 : categoryList1) {
    param.put("parentCategoryCode", row1.get("categoryCode"));
    List<Map<String, Object>> categoryList2 = this.categoryService.getCategoryList(param); 
    row1.put("subCategoryList", categoryList2);
}



마지막으로 null check 조건문만 추가하면 아래와 같은 코드가 완성된다.

for(Map<String, Object> row1 : categoryList1) {
    if(!ObjectUtils.isEmpty(row1)) {
        param.put("parentCategoryCode", row1.get("categoryCode"));
        List<Map<String, Object>> categoryList2 = this.categoryService.getCategoryList(param); 
        row1.put("subCategoryList", categoryList2);
    }
}




대분류 리스트 categoryList1 안에 있는 중분류 리스트 categoryList2 안에 있는 소분류 리스트 categoryList3 요소는 아래와 같은 자료형일 것이다.

 

대분류 리스트 자료형 : List<Map<String, Object>>
대분류 리스트 안에 중분류 리스트 자료형 : List<Map<String, List<Map<String, Object>> >>
대분류 리스트 안에 중분류 리스트 안에 소분류 리스트 자료형 : 

List<Map<String, List<Map<String, List<Map<String, Object>>  >>  >>

 

 

- 220803 

반응형