๐ ๊ฐ์
๋๋ถ๋ถ์ ํ๋ก์ ํธ์์ "๊ณตํต ์ฝ๋"๋ ํ์๋ค.
ํนํ ํ๋ก ํธ์๋์์ ๋๋กญ๋ค์ด, ์ ๋ ํธ๋ฐ์ค ๋ฑ์ ๊ทธ๋ฆด ๋ ๋ค์ํ ์ฝ๋๊ฐ ํ์ํ๋ค.
Vue.js์์ ์ฌ๋ฌ ๊ฐ์ ์ฝ๋ ๊ทธ๋ฃน์ ํ ๋ฒ์ ์์ฒญํ๊ณ , Spring ๋ฐฑ์๋์์ ๊ทธ๋ฃน๋ณ๋ก ์ฝ๋๋ค์ ๋ฌถ์ด ์๋ตํ๋ ๊ตฌ์กฐ๋ฅผ ์ค๊ณํด๋ณด์.
๐ก ๋ชฉํ
ํ๋ก ํธ์๋์์ ์ด๋ฐ ์์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด:
["position", "skill_level", "team"]
๋ฐฑ์๋์์๋ ๋ค์๊ณผ ๊ฐ์ด ๊ทธ๋ฃน๋ณ๋ก ์ ๋ฆฌ๋ ์๋ต์ ๋ฆฌํดํ๋ค:
[
{
"groupCode": "position",
"codes": [
{ "code": "dev", "name": "๊ฐ๋ฐ์" },
{ "code": "design", "name": "๋์์ด๋" }
]
},
{
"groupCode": "skill_level",
"codes": [
{ "code": "senior", "name": "๊ณ ๊ธ" },
{ "code": "junior", "name": "์ด๊ธ" }
]
}
]
๐๏ธ DB ํ ์ด๋ธ ๊ตฌ์กฐ ์์
์ฐ๋ฆฌ๋ TB_CMMN_CODE ํ ์ด๋ธ์ ๊ธฐ์ค์ผ๋ก ํ๋ค. ์ฃผ์ ์ปฌ๋ผ์ ๋ค์๊ณผ ๊ฐ๋ค:
์ปฌ๋ผ๋ช | ์ค๋ช |
CODE_TY | ์ฝ๋ ๊ทธ๋ฃน |
CODE_VALUE | ์ฝ๋ ๊ฐ |
CODE_NM | ์ฝ๋ ์ด๋ฆ |
DSPLY_ORDR | ์ ๋ ฌ ์์ |
USE_AT | ์ฌ์ฉ ์ฌ๋ถ |
๐งฑ ๋ฐฑ์๋ ๊ตฌ์กฐ ์ค๋ช
๐ VO: CommonCode.java
@Data
public class CommonCode {
private int codeId;
private String codeTy;
private String codeValue;
private String codeNm;
private int dsplyOrdr;
private String useAt;
}
๐ DTO: GroupedCodeResponse.java
@Data
public class GroupedCodeResponse {
private String groupCode;
private List<CodeItem> codes;
@Data
public static class CodeItem {
private String code;
private String name;
}
}
๐ Mapper: CommonCodeMapper.java
@Mapper
public interface CommonCodeMapper {
List<CommonCode> selectCodesByTypes(@Param("types") List<String> types);
}
<select id="selectCodesByTypes" resultType="com.example.common.vo.CommonCode">
SELECT
CODE_ID,
CODE_TY AS codeTy,
CODE_VALUE AS codeValue,
CODE_NM AS codeNm,
DSPLY_ORDR AS dsplyOrdr,
USE_AT AS useAt
FROM TB_CMMN_CODE
WHERE CODE_TY IN
<foreach collection="types" item="type" open="(" separator="," close=")">
#{type}
</foreach>
ORDER BY CODE_TY, DSPLY_ORDR
</select>
๐ Service: CommonCodeService.java
public List<GroupedCodeResponse> getGroupedCodes(List<String> types) {
List<CommonCode> codes = mapper.selectCodesByTypes(types);
return codes.stream()
.collect(Collectors.groupingBy(CommonCode::getCodeTy))
.entrySet()
.stream()
.map(entry -> {
GroupedCodeResponse response = new GroupedCodeResponse();
response.setGroupCode(entry.getKey());
List<GroupedCodeResponse.CodeItem> codeItems = entry.getValue().stream()
.map(code -> {
GroupedCodeResponse.CodeItem item = new GroupedCodeResponse.CodeItem();
item.setCode(code.getCodeValue());
item.setName(code.getCodeNm());
return item;
}).collect(Collectors.toList());
response.setCodes(codeItems);
return response;
}).collect(Collectors.toList());
}
๐งฉ ์๋น์ค๋ ์ด์ด ๋ชฉํ
- List<CmmnCodeDTO> ๋ฅผ List<GroupedCodeResponseDTO> ๋ก ๋ฐ๊พธ๋ ๊ฒ ๋ชฉ์ .
- ์ฆ, ๊ฐ ๊ทธ๋ฃน์ฝ๋(codeTy) ๋ณ๋ก codeValue, codeNm ๋ฆฌ์คํธ๋ฅผ ๋ฌถ์ด ๋ฐํ.
๐ stream ์ดํ ํ๋ฆ ํด์
return codes.stream()
- codes๋ List<CmmnCodeDTO>.
- ์ด๊ฑธ Stream<CmmnCodeDTO>๋ก ๋ฐ๊ฟ์ ์ฒ๋ฆฌ ์์.
๐ Step 1: groupingBy
.collect(Collectors.groupingBy(CmmnCodeDTO::getCodeTy))
- CmmnCodeDTO ๊ฐ์ฒด๋ค์ codeTy ๊ฐ๋ณ๋ก **Map<String, List<CmmnCodeDTO>>`๋ก ๋ฌถ์.
์๋ฅผ ๋ค๋ฉด:
{
"position": [CmmnCodeDTO(...), CmmnCodeDTO(...)],
"skill_level": [CmmnCodeDTO(...), ...]
}
๐ Step 2: entrySet().stream()
.entrySet().stream()
- ์์์ ๋ง๋ Map<String, List<CmmnCodeDTO>>๋ฅผ ๋ค์ ์คํธ๋ฆผ์ผ๋ก ๋ณํ.
- entry๋ Map.Entry<String, List<CmmnCodeDTO>> ํ์ .
โ๏ธ Map<K, V>๋ ์ํํ๊ฑฐ๋ ๊บผ๋ผ ๋ .entrySet(), keySet(), values() 3๊ฐ์ง ์ค ํ๋ ์ ํํ๋ค.
๐ Step 3: ๊ฐ ๊ทธ๋ฃน๋ณ๋ก DTO ๋ง๋ค๊ธฐ
.map(entry -> {
GroupedCodeResponseDTO response = new GroupedCodeResponseDTO();
response.setGroupCode(entry.getKey());
- GroupedCodeResponseDTO๋ ํ๋์ ๊ทธ๋ฃน์ ํํํ๋ ๊ฐ์ฒด.
- ์: groupCode = "position"
๐ Step 4: codeItems ๋ง๋ค๊ธฐ
List<GroupedCodeResponseDTO.CodeItem> codeItems = entry.getValue().stream()
.map(code -> {
GroupedCodeResponseDTO.CodeItem item = new GroupedCodeResponseDTO.CodeItem();
item.setCode(code.getCodeValue());
item.setName(code.getCodeNm());
return item;
}).collect(Collectors.toList());
- entry.getValue()๋ ๊ฐ์ codeTy๋ฅผ ๊ฐ์ง CmmnCodeDTO ๋ฆฌ์คํธ.
- ๊ฐ CmmnCodeDTO๋ฅผ CodeItem(code, name)์ผ๋ก ๋ณํํด์ ๋ฆฌ์คํธ๋ก ๋ง๋ฌ.
์:
[
{ "code": "dev", "name": "๊ฐ๋ฐ์" },
{ "code": "design", "name": "๋์์ด๋" }
]
๐ Step 5: ์ต์ข ์กฐ๋ฆฝ
response.setCodes(codeItems);
return response;
- GroupedCodeResponseDTO์ ์ฝ๋ ๋ฆฌ์คํธ๋ฅผ ๋ถ์ฌ์ ํ๋์ ๊ทธ๋ฃน ์์ฑ.
๐ Step 6: ์ ์ฒด collect
}).collect(Collectors.toList());
- ์ ๊ณผ์ ์ ๊ฑฐ์น ๋ชจ๋ ๊ทธ๋ฃน์ ๋ฆฌ์คํธ๋ก ๋ชจ์์ ๋ฆฌํด.
๐ฆ ์ต์ข ๊ฒฐ๊ณผ ํํ ์์
[
{
"groupCode": "position",
"codes": [
{ "code": "dev", "name": "๊ฐ๋ฐ์" },
{ "code": "design", "name": "๋์์ด๋" }
]
},
{
"groupCode": "skill_level",
"codes": [
{ "code": "junior", "name": "์ด๊ธ" },
{ "code": "senior", "name": "๊ณ ๊ธ" }
]
}
]
๐ Controller: CommonCodeController.java
@RestController
@RequestMapping("/api/common-codes")
@RequiredArgsConstructor
public class CommonCodeController {
private final CommonCodeService service;
@PostMapping("/batch")
public List<GroupedCodeResponse> getGroupedCodes(@RequestBody List<String> types) {
return service.getGroupedCodes(types);
}
}
๐งช ํ๋ก ํธ์๋์์ ํธ์ถ ์์ (Axios)
axios.post('/api/common-codes/batch', ["position", "skill_level", "team"])
.then(res => {
console.log(res.data);
});
โ ์ ๋ฆฌ
- ๊ณตํต ์ฝ๋ ๊ทธ๋ฃน์ ํ ๋ฒ์ ์์ฒญํด ํ๋ก ํธ์ ๋ก๋ฉ ์๊ฐ์ ์ค์ผ ์ ์๋ค.
- ์ฝ๋ ๊ทธ๋ฃน๋ณ๋ก ๋ฌถ์ด์ ์๋ต์ ๋ฐ์ผ๋ฉด ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋์์ง๋ค.
- ์ ๋ ฌ, ์ฌ์ฉ์ฌ๋ถ ํํฐ๋ง๋ ์ถ๊ฐ๋ก ๊ณ ๋ ค ๊ฐ๋ฅํ๋ค.
๐ ํ์ฅ ์์ด๋์ด
- Redis ๋ฑ ์บ์ ์ ์ฉ์ผ๋ก ์๋ ๊ฐ์
- ์ฝ๋ ์ถ๊ฐ/์์ /์ญ์ ์ ๋ํ ๊ด๋ฆฌ ๋ฐฑ์คํผ์ค ๊ตฌํ
- Swagger ๋ฌธ์ํ ๋ฐ ํ ์คํธ ์๋ํ
๋๊ธ