Spring

MyBatis

요리하다그만둠 2022. 8. 12. 15:58

참고사이트 = https://mybatis.org/mybatis-3/ko/getting-started.html

 

마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크 입니다.

마이바티스는 JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신 해줍니다. 미이바티스는 데이터베이스 레코드에 원시타입과 Map 인터페이스 그리고 자바 POJO를 설정해서 매핑하기 위해 XML가 어노테이션을 사용할 수 있습니다.

 

시작하기 위해서는 mybatis-x.x.x.jar 파일을 클래스 패스에 두어야 합니다.

메이븐을 사용한다면 pom.xml에 의존성을 주입하면됩니다.

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

XML에서 SqlSessionFactory 빌드하기

모든 마이바티스 어플리케이션은 SqlSessionFactory 인스턴스를 사용합니다.

SqlSessionFactory인스턴스는 SqlSessionFactroyBuilder를 사용하여 만들 수 있습니다.

SqlSessionFactroyBuilder는 XML 설정파일에서 SqlSessionFactroy인스턴스를 빌드할 수 있씁니다.

 

XML 파일에서 SqlSessionFactory 인스턴스를 빌드하는 것은 매우 간단합니다. 설저을 위해 클래스패스 자원을 사용하는 것을 추천하나 파일 경로나 file://URL로부터 만들어진 inputStream 인스턴스를 사용할 수도 있습니다.

마이바티스는 클래스패스와 다른 위치에서 자원을 로드하는 것으로 좀더 쉽게 해주는 Resources라는 유틸성 클래스를 가지고 있습니다.

 

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

XML 설정파일에서 지정하는 마이바티스의 핵심이 되는 설정은 트랜잭션을 제어하기 위한 TransactionManager과 함게 데이터베이스 Connection 인스턴스를 가져오기 위한 DataSource 를 포함합니다. 세부적인 설정은 간단한 예제를 통해서 보면

<?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>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

XML 가장 위부분에서는 XML 문서의 유효성체크를 위해 필요합니다. environment엘리먼트는 트랜잭션 관리와 커넥션 풀링을 위한 환경적인 설정을 나타냅니다. mappers 엘리먼트는 SQL 코드와 매핑 정의를 가지는 XML 파일인 mapper 의목록을 지정합니다.

 

XML을 사용하지 않고 SqlSessionFactory 빌드하기.

XML보다 자바를 사용해서 직접 설정하길 원한다면 XML 파일과 같은 모든 설정을 제공하는 Configuration 클래스를 사용하면 됩니다.

DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

이 설정에서 추가로 해야 할 일은 Mapper 클래스를 추가하는 것입니다. Mapper 클래스는 SQL 매핑 어노테이션을 가진 자바 클래스 입니다. 어쨋든 자바 어노테이션의 몇가지 제약과 몇가지 설정방법의 복장함에도 불구하고 XML 매핑은 세부적은 매핑을 위해 언제든 필요합니다.

 

SqlSessionFactory 에서 SqlSession 만들기

SqlSessionFactory 이름에서 보듯 SqlSession 인스턴스를 만들수 있습니다. SqlSession 은 데이터베이스에 대해 SQl 명령어를 실행하기 위해 필요한 모든 메서드를 가지고 있습니다. 그래서 SqlSession 인스턴스를 통해 직접 SQL 구문을 실행할 수 있습니다. 예를보면

 

try (SqlSession session = sqlSessionFactory.openSession()) {
  Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

좀더 좋은 방법도 생기었는데 주어진 SQL 구문의 파라미터와 리턴값을 설명하는 이너페이스(ex) BlogMapper.class)를 사용하여 문자열 처리 오류나 타입 캐스팅 오류 없이 좀더 타입에 안전하고 깔끔하게 실행할 수 있습니다.

 

예를 보면

try (SqlSession session = sqlSessionFactory.openSession()) {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
}

 

매핑된 SQL 구문 살펴보기

이 시점에 SqlSession이나 Mapper 클래스가 정확히 어떻게 실행되는지 궁금한데 매핑된 SQL 구문에 대한 내용이 가장 중요합니다. 그래서 이 문서 전반에서 가장 자주 다루어집니다. 하지만 다음의 두가지 예제를 통해 정확히 어떻게 작동하는지에 대해서는 충분히 이해가 될것입니다.

 

위의 예제 처럼 구문은 XML이나 어노테이션을 사용해서 정의할 수 있습니다. 그럼 먼저 XML 을 보면 마이바티스가 제공하는 대부분의 기능은 XML 을 통해 매핑 기법을 사용합니다. 

 

SqlSession을 호출하는 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="org.mybatis.example.BlogMapper">
     <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
     </select>
</mapper>

한 개의 매퍼 XML 파일에는 많은 수의 매핑 구문을 정의 할 수 있습니다. XML 도임부의 헤더와 doctype 을 제외하면 나머지는 쉽게 이해되는 구문의 형태입니다. 여기선 org.mybatis.example.BlogMapper 네임스페이스에서 selectBlog 라는 매핑 구문을 정의했고 이는 결과적으로 org.mybatis.example.BlogMapper.selectBlog 형태로 실제 명시되게 됩니다.

그래서 다음처럼 사용하게 되는 셈입니다.

Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);

이건 마치 패키지를 폼함한 전체 경로의 클래스태 메서드를 호출하는 것과 비슷한 형태입니다. 이 이름은 매핑된 select 구문의 이름과 파라미터 그리고 리턴타입을 가진 네임스페이스과 같은 이름의 Mapper 클래스와 직접 매핑될 수 있습니다.

이건 위에서 본것과 같은 Mapper 인터페이스의 메서드를 간단히 호출하도록 허용합니다.. 위 예제에 대응되는 형태는 아래와 같습니다.

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

두번째 방법은 많은 장점을 가집니다. 먼저 문자열에 의존하지 않는다는 것, 이는 어플리케이션을 좀더 안전하게 만듭니다 .두 번째는 개발자가 IDE를 사용할 때 매핑된 SQL 구문을 사용할떄의 수고를 덜어줍니다. 세번째는 리턴타입에 대해 타입 캐스팅을 하지 않아도 됩니다. 그래서 BlogMapper 인터페이스는 깔끔하고 리턴 타입에 대해 타입에 안전하며 이는 파라미터에도 그래도 적용됩니다.