Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

우리마의 웹 개발

[Spring Boot] Rest API 구축후 parameter를 List에 담아 MyBatis에서 처리 하는 방법(forEach문 사용) 본문

WEB/Spring Boot

[Spring Boot] Rest API 구축후 parameter를 List에 담아 MyBatis에서 처리 하는 방법(forEach문 사용)

우리마 2020. 3. 13. 14:02

지금부터 소개할 예제는 Spring Boot 환경에서 Rest API를 구축 후 paramter가 'Y' 또는 'N'과 같이 yes or no의 형태로 들어왔을 때 이를 controller에서 처리한 후 List에 담아 mybatis에서 forEach문을 이용해 결과를 출력하는 예제이다.

개발 환경
STS 4-4.5.1.RELEASE
Boot 2.2.4.RELEASE
DB POSTGRESQL - MyBatis

 

 

예제 DB 테이블

테이블 명 : testTable

name age code
one 20 01
two 21 01
three 22 02
four 30 02
a 30 01
b 30 03
c 30 04

예제에서 select구문이므로  GetMapping으로 ?param1=Y&param2=N&param3=N&param4=N 이런 식으로 요청한다. param은 code칼럼에 대응하는 것이며 Y, N으로 어떤 code를 조회할 것인지 결정하는 것이다.

완성할 SQL 예시

 

1
2
3
4
5
6
7
SELECT 
    NAME
    , AGE
    , CODE
    FROM TESTTABLE
    WHERE 1=1
    AND CODE IN('01','02','03','04');
cs

IN구문으로 어떤 code 값들을 조회할지 정한다. 이것을 MyBatis의 forEach구문으로 처리할 것이다. Y,N값으로 code값이나 빈값(' ')을 IN구문 안에 넣을지 결정한다.

ResponseDTO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.web.model.response;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestResponseDTO {
    private String name;
    private String age;
    private String code;
 
}
 
 
cs

DTO에서 결과 칼럼들을 필드에 정의한다.(SQL에서 resultMap)

@Data : getter/setter 자동 생성

@AllArgsConstructor : 모든 필드를 파라미터로 가지는 생성자 자동 생성

@NoArgsConstructor : 파라미터가 없는 디폴트 생성자 자동 생성

Entity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.web.entity;
 
import java.util.List;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestEntity {
 
    private List<String> list;
}
 
 
cs

Entity 클래스는 SQL 파라미터로 들어가는 값들을 필드로 정의하는 클래스인데(SQL에서 parameterType) 이번 예제에서 그 파라미터 값들을 List에 담아서 SQL에서 forEach루프를 돌릴 것이다.

Controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.web.controller;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.annotation.Resource;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import com.web.model.response.TestResponseDTO;
import com.web.service.TestService;
 
 
@RestController
@RequestMapping("/test")
public class TestController {
    private static final Logger log = LoggerFactory.getLogger(TestController.class);
 
    @Resource
    TestService service;
 
    @GetMapping("/array-param")
    public List<TestResponseDTO> mapReqTest(@RequestParam String param1,
                                       @RequestParam String param2,
                                       @RequestParam String param3,
                                       @RequestParam String param4)  throws Exception{
 
        log.info("param1 : "+param1);
        log.info("param2 : "+param2);
        log.info("param3 : "+param3);
        log.info("param4 : "+param4);
 
        List<String> list = new ArrayList<>();
        if(param1.equals("Y")) {list.add("01");} else {list.add("");}
        if(param2.equals("Y")) {list.add("02");} else {list.add("");}
        if(param3.equals("Y")) {list.add("03");} else {list.add("");}
        if(param4.equals("Y")) {list.add("04");} else {list.add("");}
 
        log.info("list : "+list.toString());
 
        return service.mapReqTest(list);
    }
}
 
 
cs

28 LINE : code값이 01부터 04까지 4가지 종류만 있다고 가정해서 parameter를 4개 받는다.

파라미터 앞에 @RequestParam 어노테이션을 적어줘야 get방식으로 들어오는 파라미터를 인식할 수 있다.

38 LINE : ArrayList객체를 만들고 if ~ else 문으로 Y가 들어왔을 때와 N이 들어왔을때 List에 저장할 값을 정해준다. List에 값을 넣을 때 대입 연산자(=)를 사용하면 안 된다. List 객체에 정의되어있는 삽입 메서드(add)를 사용해야 한다.

Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.web.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.web.model.response.TestResponseDTO;
import com.web.entity.TestEntity;
import com.web.mapper.TestMapper;
 
@Service
public class TestService implements TestServiceImp {
    @Autowired
    TestMapper mapper;
 
    @Override
    public List<TestResponseDTO> mapReqTest(List<String> list) {
        TestEntity entity = new TestEntity(list);
        return mapper.mapReqTest(entity);
    }
 
}
 
 
cs

Service에서 Mapper로 Entity객체를 보내는데 Mapper에서 Entity클래스의 getter를 호출해 필드에 값을 넣고 SQL을 실행한다.

Mapper , SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.web.mapper;
 
import java.util.List;
 
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Service;
 
import com.web.model.response.TestResponseDTO;
import com.web.entity.TestEntity;
 
@Service
@Mapper
public interface TestMapper {
 
    List<TestResponseDTO> mapReqTest(TestEntity entity);
 
}
 
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.web.mapper.TestMapper">
 
<select id="mapReqTest" resultMap="TestResponseDTO"  parameterType="com.web.entity.TestEntity">
 
    SELECT
          NAME
        , AGE
        , CODE
    FROM
        TESTTABLE
    WHERE 1=1
    AND CODE IN
    <foreach collection="list" item="item" separator="," open="(" close=")">
    #{item}
    </foreach>
 
</select>
<resultMap type="com.web.model.response.TestResponseDTO" id="TestResponseDTO">
    <result property="name" column="name"/>
    <result property="age" column="age"/>
    <result property="code" column="code"/>
</resultMap>
</mapper>
 
cs

위에서 말했듯이 DTO를 resultMap으로, Entity를 parameterType으로 설정해준다.

17 LINE : forEach는 myBatis의 반복문이다. 

collection - 전달받은 파라미터 명

item - 파라미터 명을 다른 이름으로 대체

open - 반복문 시작할 때 적을 문구

close - 반복문 끝날 때 적을 문구

separator -  한번 반복될 때마다 적을 문구

 

실행 , 결과

http://localhost:8080/test/array-param? param1=Y&param2=N&param3=N&param4=N

브라우저에 입력

param1 에만 Y를 적어서 code 값이 01인 row만 출력되는 것을 확인할 수 있다.

로그도 잘 찍힌다. 결과 SQL에서 param1만 Y로 넘어왔다는 것을 확인할 수 있다.

 


댓글로 질문, 지적 환영합니다.

Comments