IT/development

[mybatis] mybatis parameter 여러개 전달

알 수 없는 사용자 2022. 11. 22. 06:56
반응형

목차

    예를 들어 String타입의 "status"와 Long타입의 no, 2개의 parameter값을 받아서 테이블 업데이트 하려는 로직이 있을 시 VO째로 넘기기엔 뭔가 비효율적이고 다른사람이 코드를 봤을 때도 직관적이지 않아 보였다.

    물론 추후에 넘기는 parameter값이 추가될 경우엔 VO째로 넘기는게 확장성이 있겠지만 이 기능은 그런게 아니었다.

    그래서 구글링 하다가 역시나 방법을 찾아서 미래의 내가 보기위해 기록한다.

    1. HashMap 이용 😄

    Controller에서 HashMap에 담아서 넘기는 방법

    Controller

    HashMap에 parameter값 담아서 전달

    HashMap<String, Object> param = new HashMap<>();
    param.put("no", no);
    param.put("status", status);

    Service

    public void updateStatus(HashMap<String, Object> param) throws Exception;

    impl

    public void updateStatus(HashMap<String, Object> param) throws Exception {
    	userMapper.updateStatus(param);
    }

    Mapper

    public void updateStatus(HashMap<String, Object> param);

    xml

    parameterType을 "HashMap"으로 설정

    <update id="updateStatus" parameterType="HashMap">
    UPDATE member
        SET status = #{status, jdbcType=VARCHAR}
        WHERE no = #{no, jdbcType=BIGINT}
    </update>

    2. @Param 이용 😃

    Controller에서 parameter값 2개를 각각 넘기고 mapper에서 @Param 어노테이션 적용, xml에서 parameterType을 map으로 작성

    Controller

    userService.updateStatus(no, status);

    Service

    public void updateStatus(Long no, String status) throws Exception;

    impl

    public void updateStatus(Long no, String status) throws Exception {
    	userMapper.updateStatus(no, status);
    }

    mapper

    넘길 parameter값에 @Param 적용

    import org.apache.ibatis.annotations.Param;
    
    public void updateStatus(@Param("no") Long no, @Param("status")String status);

    xml

    parameterType을 "map"으로 설정

    <update id="updateStatus" parameterType="map">
    UPDATE member
        SET status = #{status, jdbcType=VARCHAR}
        WHERE no = #{no, jdbcType=BIGINT}
    </update>

    기타, parameter 중 배열이 있는 경우

    [ex](Long memNo, Long[] ClientNo)를 넘기는 경우 

    DB에 insert 시 param값 2개를 받는데 그 중 1개는 단일값, 나머지 1개는 배열로 받는 경우였음

    필드값이 2개밖에 없어서 DTO를 만들기는 귀찮았음

    오랜 삽질 끝에 내가 시도한 방법은 아래처럼 처리했음(물론 다른 방법도 있음)

    Controller

    @RequestParam(required = true) Long[] code_seq,        
    생략...
    // 테이블 저장 시 selectKey로 뽑은 값이 VO에 저장됨
    TestService.insert(VO);
    // 매핑 테이블 저장 시 위의 vo에 담긴 seq값을 넘김, code_seq는 클라이언트에서 받는 배열값
    Service.insertMapping(VO.getSeq(), code_seq);

    service

    public void insertMapping(Long seq, Long[] code_seq) throws Exception {
    		Mapper.insertMapping(seq, code_seq);
    	}

    mapper

    역시 parameter값이 1개 이상이라 @param을 명시함

    public void insertMapping(@Param("seq") Long seq, @Param("code_seq") Long[] code_seq);

    xml

    <insert id="insertMapping" parameterType="map">
    		INSERT INTO mapping
    		(
    		 	seq,
    			code_seq,
    			reg_date
    		)
    		VALUES
            <!-- 이 경우는 collection에 array가 아니라 parameter값으로 넘긴 변수명을 입력해야 함--> 
    		<foreach collection="code_seq" item="code_seq" separator=",">
    		(
    		 	#{seq},	<!-- 단일값으로 넘긴 param값 -->
    		 	#{code_seq},	<!-- 배열로 넘긴 param값 --> 
    			NOW()
    		)
    		</foreach>
    	</insert

     

    반응형