<< 학습 목표 >>

1. INSERT 한 데이터의 PK 값을 돌려받을 수 있다.


프로젝트의 규모가 커지면 하나의 처리를 하기 위해서 쿼리를 여러번 실행해야하는 경우가 자주 발생함

우리는 지금까지 단편적인 기술만 배웠으므로 그런일이 없었지만 곧 지금까지 배운 것들을 종합적으로 활용해서 하나의 프로젝트를 만들어볼 예정임

 

이렇게 하나의 처리를 하기 위해서 쿼리를 여러 번 실행해야할 때 INSERT 후 INSERT 한 데이터의 PK 값을 사용해 그 다음 쿼리들이 동작해야하는 경우가 있음

 

좀 더 구체적인 예를 들어보자

[ 스터디 그룹 모집 사이트 개발 하기 ] 프로젝트를 하는 상황인데 스터디 그룹 모집 글을 작성하고 다른 사용자들이 이 모집 글에 그룹원 신청을 하는 기능이 있다고 상상하자

 

이를 위해서 DB를 다음과 같이 구성했음

StudygroupInfo 테이블 : 스터디 그룹 모집 글 정보가 저장되는 테이블

StudygroupMember 테이블 : 스터디 그룹원의 정보가 저장되는 테이블

 

한 회원이 스터디 그룹 모집 글을 작성하면 StudygroupInfo 테이블에 모집 글 정보가 저장됨

모집 글을 작성한 사람은 스터디 그룹원(StudygroupMember)이므로 모집 글을 StudygroupInfo 테이블에 INSERT 후 바로 이어서 INSERT 한 모집 글의 idx를 사용해 StudygroupMember 테이블에 글을 작성한 회원의 정보를 저장해야함

 

이 처리를 구현한 쿼리, DAO, 컨트롤러를 보자

코드를 입력할 필요는 없고 코드만 보면 됨

 

<< 쿼리 >>

<?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.study.chapter04.StudygroupDao">
	<insert id="saveStudygroupInfo" parameterType="com.study.chapter04.StudygroupInfo">
		INSERT INTO studygroupInfo(title, contents, regDate) VALUES(#{title}, #{contents}, CURRENT_TIMESTAMP());
	</insert>
	
	<select id="getStudygroupIdx" parameterType="com.study.chapter04.StudygroupInfo" resultType="_int">
		SELECT idx FROM studygroupInfo WHERE id = #{id} AND pw = #{pw};
	</select>
	
	<insert id="joinStudygroupMember" parameterType="com.study.chapter04.StudygroupMember">
		INSERT INTO studygroupMember(studygroupIdx, memberIdx) VALUES(#{studygroupIdx}, #{memberIdx});
	</insert>
</mapper>

 

<< DAO >>

package com.study.chapter04;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface StudygroupDao {
	void saveStudygroupInfo(StudygroupInfo studygroupInfo);
	int getStudygroupIdx(StudygroupInfo studygroupInfo);
	void joinStudygroupMember(StudygroupMember studygroupMember);
}

 

<< 컨트롤러 >>

package com.study.chapter04;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;

import jakarta.servlet.http.HttpSession;

@Controller
public class StudygroupController {
	@Autowired
	private StudygroupDao studygroupDao;
	
	@PostMapping()
	public void saveStudygroupInfo(StudygroupInfo newStudygroupInfo, HttpSession session) {
		// 스터디 그룹 모집 글 저장
		studygroupDao.saveStudygroupInfo(newStudygroupInfo);
		
		// 로그인한 사용자 번호
		int loginUserIdx = (int) session.getAttribute("loginUserIdx");
		// 스터디 그룹 번호
		int studygroupIdx = studygroupDao.getStudygroupIdx(newStudygroupInfo);
		
		// 모집글을 작성한 사용자는 작성한 모집글의 스터디 그룹원이므로
		// 작성한 모집글의 스터디 그룹원으로 등록하기 위한 정보 생성
		StudygroupMember studygroupMember = new StudygroupMember();
		studygroupMember.setMemberIdx(loginUserIdx);
		studygroupMember.setMemberIdx(studygroupIdx);
		
		// 모집글을 작성한 사용자를 작성한 모집글의 스터디 그룹원으로 등록
		studygroupDao.joinStudygroupMember(studygroupMember);
	}
	
}

 

앞서  언급했듯 [ 스터디 그룹 모집글 작성 ] 이라는 하나의 처리를 하기 위해서 INSERT, SELECT, INSERT 쿼리가 순차적으로 동작해야함

 

이때, INSERT한 스터디 그룹 번호를 찾기 위해 SELECT를 하는데 이런 경우 여러 가지 문제가 생길 수 있는데 대표적으로 우연찮게 똑같은 제목, 내용의 모집 글이 있을 경우 올바른 스터디 그룹 번호를 조회할 수 없음


이렇게 방금 INSERT 한 데이터의 PK 값이 필요할 때 얻는 방법을 알아보자

 

방금 INSERT 한 데이터의 PK 값이 필요할 때는 insert 태그에 useGeneratedKeys 속성과 keyColumn 속성을 사용하면됨

아래와 같이 useGeneratedKeys 속성 값은 true 로 주고 keyColumn 속성은 PK 칼럼명을 주면 됨

 

이렇게 insert 태그를 구성하면 INSERT 후에 INSERT 한 데이터의 PK 값을 INSERT 할 때 매개변수로 전달한 DTO에 담아줌

 

 

바뀐 컨트롤러, DAO, 쿼리와 흐름을 한번에 보자

 

특히, 컨트롤러에서 INSERT 한 스터디 그룹 번호를 가져오기 위해 select가 빠졌다는 점에 주목하자

728x90
LIST