Persistence Framework/SQL Mapper-Mybatis

동적 쿼리 foreach문

prden 2021. 6. 3. 19:28

1. 태그

1)  collection : 전달받은 인자로 List or Array형태만 가능하다

2) item : 전달받은 인자 값을 alias 명으로 대체

3) open : 구문이 시작될 때 삽입할 문자열

4) close : 구문이 종료될 때 삽입할 문자열

5) index : 반복되는 구문 번호로 0부터 순차적으로 증가한다.

 

2. 사용 예시 -1

1) controller에서 불러올 때 인자 값 fileno

Controller에서 

        String[] fileno = request.getParameterValues("fileno");
        boardDetailsDao.insertBoard(boardInfo, filelist, fileno);

2) DaoImpl에서 hashmap으로

		if (fileno != null) {
                HashMap<String, String[]> fparam = new HashMap<String, String[]>();
                fparam.put("fileno", fileno);
                sqlSessionTemplate.insert("deleteBoardFile", fparam);
            }

3) 실제 xml에서 아래와 같이 사용한다. 

	<delete id="deleteBoardFile" parameterType="hashmap">
        DELETE FROM BOARD_FILE
        WHERE FILE_NO IN(
            <foreach item="item" index="index" collection="fileno" separator=",">
                ${item}
            </foreach>
            )
    </delete>

위에서는 open, close 생략하고 "(", ")" 직접 넣어주었다.

collection에 인자 값으로 fileno 주고, item으로 alias 줘서 ${item}으로 넣어주는 것이다. 

 

아래는 실제 공식문서에 나와있는 예시이다. 

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

 

3. 사용예시 -2

<foreach collection="List or Array" item="alias" ></foreach>

3-1.  배열 파라미터를 직접 넘기는 경우

 

DAO

public List getAuthUserList(String [] userArray) {

     return sqlSession.selectList("getAuthUserList", userArray);

 }

 

USER-Mapper.xml

<select id="getAuthUserList" resultType="members">

SELECT m.*,a.name FROM members AS m JOIN authority AS a ON m.authority = a.authority WHERE m.authority IN

<foreach collection="array" item="arr" open="(" close=")" separator=","> #{arr} </foreach>

ORDER BY m.authority; </select>

 

※ 주의 : collection을 꼭! "array"로 작성해야 된다. 

 

3-2 배열 파라미터 직접 넘기는 경우2

for (Map<String, Object> product : list) {
   if(product.get("IMAGES")!=null) {
      List<Map<String, Object>> imageList = dao.getSqlSessionTemplate().selectList("storeProduct.productImageList", product.get("IMAGES").toString().split(","));
      product.put("imageList", imageList);
   }
}

 storeProduct.xml 파일
<select id="productImageList" resultType="hashmap">
        SELECT
        FILE_PATH
        ,MAIN_IMG_YN 
        ,ALT 
        FROM TBL_FILE_STORE
        WHERE 1=1
        AND FILE_GRP_SEQ IN
        <foreach item="image" index="index" collection="array" open="(" separator="," close=")">
            #{image}
        </foreach>

3-2 아래는 내가 실제 사용한 예시이다. 

 

board-mapper.xml

 <select id="selectBoardCount" resultType="Integer" parameterType="com.legalcounsel.Board.BoardSearchVO">
    SELECT COUNT(*)
        FROM BOARD TB
        INNER JOIN BOARD_GROUP TBG ON TBG.BG_NO = TB.BG_NO
        INNER JOIN USER CU ON TB.USER_ID = CU.USER_ID
        <include refid="includeBoard"/>
    </select>
 
 <sql id="includeBoard">
        WHERE BRD_DELCHECK='N' AND BG_DELCHECK='N'
        <if test="bgno!=null and bgno!=''">
            AND TB.BG_NO=#{bgno}
        </if>
        <if test="searchKeyword!=null and searchKeyword!='' and searchType!=''">
            <foreach item="item" index="index" collection="searchTypeArr" separator=" OR " open="AND (" close=")">
                ${item} LIKE CONCAT('%', #{searchKeyword},'%' )
            </foreach>
        </if>
    </sql>
    
    
    <!--    ### 검색 동적 쿼리 WHERE 부분 잘 확인
               SELECT COUNT(*)FROM BOARD TB -->
    <!--     INNER JOIN BOARD_GROUP TBG ON TBG.BG_NO = TB.BG_NO-->
    <!--     INNER JOIN USER CU ON TB.USER_ID = CU.USER_ID  -->
    <!--     WHERE BRD_DELCHECK='N' AND BG_DELCHECK='N' -->
    <!--     AND (BRD_TITLE LIKE CONCAT('%', ?,'%' )OR BRD_MEMO LIKE CONCAT('%', ?,'%' ))-->

 

<foreach item="item" index="index" collection="searchTypeArr" separator=" OR " open="AND (" close=")">
                ${item} LIKE CONCAT('%', #{searchKeyword}, '%' )
 </foreach>

 

searchTypeArr 위해서 Getter 있어야 한다. 

 

@Getter
@Setter
public class BoardSearchVO extends PageVO {
    private String bgno;    //게시판 그룹
    private String searchKeyword;   //검색 키워드(globalKeyword)
    private String searchType ="";  //검색 필드: 제목(brd_title), 내용(brd_memo)
    @Getter(AccessLevel.NONE)
    private String[] searchTypeArr;     //검색 필드를 배열로 반환 검색위해서(foreach 동적 쿼리)
    private String searchExt1="";       //검색 확장 필드

    public String[] getSearchTypeArr() {
        return searchType.split(",");
    }
}

 

 

 

참조 : https://java119.tistory.com/85 

 

[MyBatis] 동적 쿼리 foreach문 문법 총 정리

시작하기에 앞서 참고 자료 *ibatis iterate문 지원 태그 property : 파라미터명 prepend : 쿼리로 쓰일 문자 open : 구문이 시작될때 삽입할 문자열 close : 구문이 종료될때 삽입할 문자열 conjunction :..

java119.tistory.com

 

다른 동적쿼리 예시

 

https://sinna94.tistory.com/entry/MyBatis-%EB%8F%99%EC%A0%81-%EC%BF%BC%EB%A6%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0 

 

MyBatis - 동적 쿼리 사용하기

1. 기본적인 동적 쿼리 SELECT * FROM KH.EMPLOYEE WHERE ${searchType} = #{keyword} map 형식으로 검색 타입과 키워드를 받아와서 처리했다. WHERE 절에서 검색 타입은 ${ } 로 전달하며 키워드는 #{ } 로 전달..

sinna94.tistory.com

 

'Persistence Framework > SQL Mapper-Mybatis' 카테고리의 다른 글

selectkey 사용방법  (0) 2021.06.04
Mybatis-spring 모듈  (0) 2021.05.02
마이바티스 설정 파일(mybatis-config.xml)  (0) 2021.05.01