Hayden's Archive

[Spring/MyBatis] VO 필드명, DB 컬럼명이 다를 경우 xml 처리 본문

Study/DB

[Spring/MyBatis] VO 필드명, DB 컬럼명이 다를 경우 xml 처리

_hayden 2020. 8. 4. 17:38

VO 필드명

 

DB 컬럼명

 

자바에서는 주로 Camel Case를 쓰는 반면, DB에서는(+파이썬에서도) Snake Case를 쓴다. 그러다 보니 VO 필드명과 DB 테이블 컬럼명이 불일치하는 경우가 생길 수 있다.

위에서는 userId, userName과 user_id, user_name이 서로 불일치한다.

 

 

단위 테스트 코드

package ibatis.services.user.test;

import ibatis.services.domain.User;

import java.io.Reader;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisTestApp01 {
	public static void main(String[] args) throws Exception{

		Reader reader=Resources.getResourceAsReader("config/SqlMapConfig.xml");
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);		
		SqlSession session=factory.openSession();
        
		List<User> list=session.selectList("UserMapper.getUserList");
		
		//0. getUserList :: 모든 user 정보
		System.out.println(":: 0. all User(SELECT)  ? ");
		
		for (int i =0 ;  i < list.size() ; i++) {
			System.out.println( "<"+ ( i +1 )+"> 번째 회원.."+ list.get(i).toString() );
		}
	}
}

 

 

단위 테스트를 할 때, SQL 쿼리문 xml을 다음과 같이 작성하면 에러가 난다.(vo 필드명과 DB 컬럼명이 달라서 null값으로 나옴)

<?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">

<!-- SQL definition -->
<mapper namespace="UserMapper">
	<select id="getUserList" resultType="user">
		SELECT
 		user_id, 
 		user_name, 
 		password, 
 		age, 
 		grade, 
 		reg_date
 		FROM users
 		ORDER BY user_id
	</select>
</mapper>

 

 

방법1) SQL문에 AS로 써주기 (컬럼명과 필드명이 동일할 경우에는 AS를 굳이 안 써줘도 되지만, 쓰는 김에 함께 써주는 편이다.)

<?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">

<!-- SQL definition -->
<mapper namespace="UserMapper">
	<select id="getUserList" resultType="user">
		SELECT
 		user_id AS userId, 
 		user_name AS userName, 
 		password AS password, 
 		age AS age, 
 		grade AS grade, 
 		reg_date AS regDate
 		FROM users
 		ORDER BY user_id
	</select>
</mapper>

 

 

방법 2) <resultMap> 사용해서 Mapping하기

쿼리문을 여러개 작성해야 할 때 매번 AS로 처리해주면 번거롭다. 그래서 다음과 같이 <resultMap>을 사용한다.(SELECT 쿼리문에서만 사용됨)

* 참고

정적인 쿼리(Static Query)
: SELECT문에서 WHERE절 조건을 어떻게 주느냐에 따라서 계속적으로 서로 다른 SELECT문이 만들어지는 쿼리

동적인 쿼리(Dynamic Query)
 : SELECT문에서 WHERE절 조건이 바뀌더라도 하나의 SELECT문으로 커버될 수 있는 쿼리
 즉, 하나의 SELECT문으로 4,5개 이상의 WHERE절을 소화할 수 있다.
<?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">
<!--
	SQL 구문의 재사용
	1) sql    2) include
-->
<mapper namespace="UserMapper">
	<!-- 이렇게 맞춰 놓으면 밑에서 AS 안 써도 됨 -->
	<resultMap type="user" id="userSelectRM">
		<result property="userId" column="user_id"/>
		<result property="userName" column="user_name"/>
		<result property="password" column="password"/>
		<result property="age" column="age"/>
		<result property="grade" column="grade"/>
		<result property="regDate" column="reg_date"/>
	</resultMap>
	
	<sql id="select-users">
		SELECT
 		user_id, user_name, password, age, grade, reg_date
 		FROM users
	</sql>
	<sql id="orderby-userid-desc">
		ORDER BY user_id DESC
	</sql>
 	<select id="getUserList" parameterType="string" resultType="user" resultMap="userSelectRM">
 		SELECT
 		user_id, user_name, password, age, grade, reg_date
 		FROM users
 		WHERE user_name=#{value}
 	</select>
 	
 	<select id="getUserList01" parameterType="user" resultType="user" resultMap="userSelectRM">
 		<include refid="select-users"/>
 		<where>
 			<if test="userName !=null">
 				user_name LIKE #{userName}
 			</if>
 			<if test="age !=null">
 				OR age LIKE #{age}
 			</if>
 		</where>
 		<include refid="orderby-userid-desc"/>
 	</select>
</mapper>

 

 

방법 3) MyBatis 설정문서에서 setting을 통해 설정

userId, user_id와 같이 Camel Case, Snake Case로만 분명하게 다른 경우에만 해당됨.

참고 - JDBC 프레임워크는 컬럼명과 필드명이 다르면 알아서 Camel Case로 바꿔준다. 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 1. properties 파일 연결 -->
	<properties resource="config/dbconn.properties"></properties>

	<settings>
		<!-- Camel Case, Snake Case로만 다를 경우 
        	resultMap을 안 써도 이 코드 쓰면 알아서 바꿔줌 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>

	<!-- 2. vo 연결 및 alias 지정 -->
	<typeAliases>
		<typeAlias type="ibatis.services.domain.User" alias="user"/>
	</typeAliases>

	<!-- 3. DB 서버 정보 -->
	<environments default="develop">
		<environment id="develop">
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="UNPOOLED">
				<property name="driver" value="${jdbc.mysql.driver}"/>
				<property name="url" value="${jdbc.mysql.url}"/>
				<property name="username" value="${jdbc.mysql.username}"/>
				<property name="password" value="${jdbc.mysql.password}"/>
			</dataSource>
		</environment>
	</environments>	

	<mappers>
		<mapper resource="sql/mybatis-userservice-mapping.xml"/>
	</mappers>
</configuration>