본문 바로가기
TIL

MyBatis foreach 반복문에 List 자료형 parameterType 사용하기

by thegreatjy 2024. 1. 28.
728x90

실행환경

- SpringBoot: 3.0.0
- MyBatis: org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.1
- MariaDB: 2.7.3

나의 요구사항

List<Integer, Integer> 리스트를 돌면서 update 문을 여러 개 실행시키고 싶었다.

update 테이블 set 컬럼=[list.get(i)] where 컬럼=[i] <- 이 쿼리를 i번(리스트 크기) 실행시키고 싶었다.

해결방법

1. jdbc url에 ?allowMultiQueries=true 추가하여 다중쿼리 작업을 허용한다.

나는 인코딩이랑 서버 시간 설정이 기본적으로 있어서 유지하였다.

url: jdbc:mariadb://localhost:포트번호/디비명?characterEncoding=UTF-8&serverTimezone=UTC&allowMultiQueries=true



2. service 단 코드
트랜잭션 처리는 아직 안 했다.

@Transactional
    public boolean modifyOrders(List<Integer> newOrders) {
        Integer result = categoryMapper.updateOrders(newOrders);

        if(result > 0)  return true;
        else        return false;
    }



3. mapper.xml 코드
공식 문서를 보면 index가 리스트의 인덱스 순서, 아이템이 리스트의 값이 들어있다고 한다.
그리고 separator로 ;를 지정해주어야 한다.
지정해주지 않으면 update-set-where-update-set-where-이런식으로 실행되어 오류가 발생한다.
지정해주면 update-set-where-;update-set-where-; 이렇게 실행되는 것으로 바뀐다.

<update id="updateOrders" parameterType="java.util.List">
  <foreach collection="list" index="index" item="item" separator=";">
    update tb_category
    set orders = #{index} + 1
    where id = #{item}
  </foreach>
</update>






...
list말고 map으로 반복문을 돌리고 싶었는데 잘 되지 않았다. 오래 검색한 것이 아까워서 괜찮았던 참고 사이트를 기록하려고 한다..... 아까워...
다시 생각해 보니까 굳이 map을 쓸 필요는 없었기에 list를 사용하였다.

- https://mybatis.org/mybatis-3/dynamic-sql.html#foreach

- https://stackoverflow.com/questions/18388936/how-to-iterate-through-hashmap-in-mybatis-foreach



- References

https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=jhj9512z&logNo=222264090334&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView

https://stackoverflow.com/questions/33372524/java-mybatis-multiple-update-statements

728x90