아래와 같은 Mapper xml의 쿼리 문이 있다고 할 경우,

<insert id="insertMember">
	insert into tbl_member (userid, userpw, username, email) values 
	(#{userid}, #{userpw}, #{username}, #{email})
</insert>

VO 객체는 다음과 같고,

public class MemberVO {
	private String userid;
	private String userpw;
	private String username;
	private String email;
	private Date regdate;
	private Date updatedate;

	... 이하 getter, setter는 생략 ...
}

DAO에서 Mapper xml에 있는 쿼리 실행을 다음과 같이 한다고 할때,

public void insertMember(MemberVO vo) {
	sqlSession.insert(namespace + ".insertMember", vo);
}

이럴때 sqlSession.insert(namespace + ".insertMember", vo)에서 vo 객체를 Mapper로 넘기면 #{userid}, #{userpw}, #{username}, #{email} 값들과 vo가 어떻게, 어떤 원리에 의해서 매핑이 되는가?

SqlSession 클래스의 insert() 메소드를 보면 다음과 같이 API 설명이 되어 있다.
int insert(String statement, Object parameter)
   ==>Execute an insert statement with the given parameter object. Any generated autoincrement 
   ==>values or selectKey entries will modify the given parameter object properties. 
   ==>Only the number of rows affected will be returned.
   Parameters:
     -. statement : Unique identifier matching the statement to execute.
     -. parameter : A parameter object to pass to the statement.
   Returns:
     -. int : The number of rows affected by the insert.

이 메소드의 첫 번째 매개인자인 statement는 이 statement의 문자열과 1:1로 대응되는 Mapper xml 파일에 있는 쿼리문을 지칭하게 된다.
이때 Mapper의 id값과 statement의 문자열이 동일한 쿼리문에 매핑된다.
위의 예에서는 Mapper xml 파일에서 id가 insertMember인 쿼리문을 실행하게 된다.

<insert id="insertMember">
	insert into tbl_member (userid, userpw, username, email) values 
	(#{userid}, #{userpw}, #{username}, #{email})
</insert>

두 번째 매개인자인 parameter는 첫 번째 매개인자인 statement가 가리키는 Mapper 클래스의 쿼리문을 실행할 때 이 쿼리문에서 사용할 변수들에(#{userid}, #{userpw}, #{username}...) 넘겨줄 값을 담고 있다. 
위이 예에서는 MemberVO 클래스의 객체인 vo가 되겠다.
이때 vo가 클래스가 가지고 있는 값들과 #{userid}, #{userpw}, #{username}, #{email} 이 변수들이 어떤 원칙에 의해서 연동되는가 하는 것이다.

이때 두 번째 매개인자인 parameter에는 다음과 같은 다양한 종류들이 가능한데

1) parameter가 하나이고 기본 자료형이나 문자열인 경우 값이 그대로 전달된다.

public MemberVO readMember(String userid) throws Exception {
	return (MemberVO)sqlSession.selectOne(namespace+".selectMember", userid);
}

Mapper xml에서는 userid와 동일한 mapper 변수와 1:1로 대응된다. 이 경우는 #{userid} = userid가 되는 것이다.

<select id="selectMember" resultType="org.zerock.domain.MemberVO">
	select 
	*
	from tbl_member
	where userid = #{userid}
</select>

2) parameter가 클래스의 객체인 경우 해당 클래스의 getter 메소드에 대응되서 mapper 변수가 값을 획득한다.
위의 vo 객체의 경우인 #{userid}, #{userpw}, #{username}, #{email}는 각각 vo 객체의 getUserid(), getUserpw(), getUsername(), getEmail()을 통해서 이들 각각의 Mapper 변수들의 값을 할당받게 된다.
만일 MemberVO 클래스의 멤버 변수에 dayCalc는 존재하지 않지만 MemberVO 클래스에 getDayCalc()이라는 getter가 만들어져 있다면 Mapper 변수에 #{dayCalc}과 같이 표현하면 정상적으로 값을 가져올 수 있게된다.

3) parameter가 클래스의 객체는 아니나 Mapper로 넘겨야 할 파라미터가 2개 이상일 경우 Map에 담아서 넘기는데 이 경우의 1:1 대응 원칙은 다음과 같다.

public MemberVO readWithPW(String userid, String userpw) throws Exception {
	Map<String, Object> paramMap = new HashMap<String, Object>();
	paramMap.put("userid",  userid);
	paramMap.put("userpw", userpw);
		
	return sqlSession.selectOne(namespace+".readWithPW", paramMap);
}

<select id="readWithPW" resultType="org.zerock.domain.MemberVO">
	select
		*
	from tbl_member
	where userid = #{userid} and userpw = #{userpw}
</select>

이 경우는 Map 객체의 key값과 Mapper의 변수가 1:1로 대응되서 값이 전달된다.
즉 Map 객체의 key 이름과 Mapper xml의 변수 이름이 동일해야 한다.

이상의 원리를 따라 MyBatis Mapper xml의 쿼리문과의 연동은 SqlSession 클래스가 알아서 매핑 작업을 처리해 준다.




+ Recent posts