Database ( DB )/ibatis, mybatis

[Spring boot] mybatis alias 사용법

노루아부지 2022. 3. 6. 21:07

MyBatis를 사용할 때 sql에 parameterType 또는 resultType의 값으로 VO, DTO 클래스들을 넘길 때, 패키지 경로까지 모두 써야 하는 불편함이 있습니다.

 

예를 들어 다음과 같습니다.

1) User.java

package com.example.demo;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
  private String userId;
  private String userName;
}

 

2) UserMapper.xml

<?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.example.demo.UserMapper">
  <select id="findById" resultType="com.example.demo.User">
    select * from tb_user where user_id = #{userId}
  </select>

  <select id="findAll" resultType="com.example.demo.User">
    select * from tb_user
  </select>
</mapper>

 

 

간단한 설정으로 Class명만 입력하게 할 수 있습니다.

 

1. application.properties 파일에 다음과 같은 옵션을 추가합니다.

# xml파일 result type에 패키지명을 생략할 수 있도록 alias 설정
mybatis.type-aliases-package=com.example.demo

 

2. UserMapper.xml을 다음과 같이 수정합니다.

아래와 같이 resultType을 User로 변경합니다.

<?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.example.demo.UserMapper">
  <select id="findById" resultType="User">
    select * from tb_user where user_id = #{userId}
  </select>

  <select id="findAll" resultType="User">
    select * from tb_user
  </select>
</mapper>

 

끝입니다. 이렇게 하는 것만으로 해결됩니다.

단, 이름으로 찾는 것이기 때문에 설정된 경로 (여기서는 com.example.demo)에는 반드시 중복된 이름이 존재하면 안 됩니다.

예를 들어 다음과 같은 경우입니다.

 

위의 예시를 보면 User 클래스 파일은 다음과 같은 두 개의 패키지 내에 각각 존재합니다.

  • com.example.demo
  • com.example.demo.test

 

이 상태에서 프로그램을 실행하면 다음과 같은 에러가 발생합니다.

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in file [E:\개발\mybatis\build\classes\java\main\com\example\demo\UserService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userMapper' defined in file [E:\mybatis\build\classes\java\main\com\example\demo\UserMapper.class]: Cannot resolve reference to bean 'sqlSessionTemplate' while setting bean property 'sqlSessionTemplate'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sqlSessionTemplate' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Unsatisfied dependency expressed through method 'sqlSessionTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.apache.ibatis.type.TypeException: The alias 'User' is already mapped to the value 'com.example.demo.User'.

 

 

내용은 길지만, 핵심은 이 한 문장입니다.

 

The alias 'User' is already mapped to the value 'com.example.demo.User'.

 

com.example.demo 패키지와 그 하위 패키지 모두 포함하여 User라는 이름이 2개 존재한다는 것입니다.

 

이때 둘 중 하나의 이름을 변경하는 것도 방법이지만 다음과 같은 방법도 있습니다.

package com.example.demo.test;

import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.type.Alias;

@Getter
@Setter
@Alias("UserDTO")
public class User {
  private String userId;
  private int age;
}

 

이렇게 com.example.demo.test의 User의 Alias를 UserDTO로 변경하는 것입니다.

이렇게 하면 com.example.demo의 User는 User로 인식하고 test의 User는 UserDTO로 인식하게 됩니다.

 

728x90
loading