MyBatis와 스프링 연동

cy8erpsycho·2023년 8월 22일
0

스프링

목록 보기
7/29
post-thumbnail

MyBatis

SQL Mapping 프레임워크

  • SQL과 Object간의 관계를 매핑해주는 역할
  • JDBC코드에 비해 처리하는 부분이 간결해지고, close처리등이 지원

Spring에서의 사용

  • 스프링은 MyBatis와의 연결을 위한 mybatis-spring 라이브러리을 이용해서 연동 처리


MyBatis 관련 라이브러리 추가

MyBatis와 mybatis-spring을 사용하기 위해서 pom.xml 파일에 추가적인 라이브러리들을 설정해야 한다.

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>![]

위의 라이브러리를 적용한 pom.xml은 다음과 같다.

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>1.3.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
</dependency>		

호환성 확인

각 버전마다 ComPile Dependencies를 확인해서 호환이 잘되는 버전을 확인할 수 있다.

Provided Dependencies 에서는 Version과 Updates를 확인해서 자신의 버전에 맞는 라이브러리를 설치한다.


SQLSessionFactory

  • root-context.xml에 MyBatis 설정
  • MyBatis의 핵심 객체는 SqlSessionFactory타입의 객체
  • SqlSessionFactoryBean은 내부적으로 MyBatis의 SqlSessionFactory를 생성

root-context.xml에 다음과 같은 형태로 작성한다.

<!-- HikariCP configuration -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>

<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>

스프링과의 연동 처리

Mapper인터페이스

  • Class : 직접 일을 하기 위해서, 메소드의 body(일을 하기 위해 가지는 로직 부분)를 구현해야 한다. 즉, 일을 할 수 있는 능력을 가지고 있는 것이 class라고 이해할 수 있다. 그 클래스들의 모든 메소드가 일을 할 수 있는 능력을 가지는 바디를 가지게 되면 그 클래스는 객체를 만들 수 있고 만든 객체에게 메세지를 전달해서 원하는 일을 수행하게 할 수 있다. 이렇게 객체를 생성할 수 있는 Class를 Concrete Class라 한다.
    메소드가 선언되어 있는데 바디가 없는 메소드가 있다. 이는 abstract 키워드를 가진다. 일을 할 수 있는 능력이 없다는 뜻이다. astract 메소드를 가지는 Class가 abstract Class가 된다. abstract class는 일을 시킬 능력이 없다. 이는 객체를 만들 수 없다는 뜻이다. 객체를 생성하기 위해서는 반드시 모든 메소드가 바디를 가지고 있어야한다. 그래서 abstract class를 상속받게 되면 내가 이 메소드의 바디를 구현해야 한다. abstract class는 바디가 있는 메소드도 있고 바디가 없는 메소드도 있다.
  • 인터페이스 : 모든 메소드가 바디가 없는 경우의 Class 이다. 약속만 잔뜩 만들어놓고 일을 할 능력이 없는 것을 뜻한다. 즉, 가지고 있는 모든 메소드가 abstract이고 만약 이 인터페이스를 구현을 할 때는 메소드의 바디를 강제로 구현해야 함을 뜻한다. 이를 강제구현명세서라 부르기도 한다. 기능을 선언을 하고 반드시 구현해야 한다는 것을 뜻한다.

Mapper 설정

MyBatis가 동작할 때 Mapper를 인식할 수 있도록 root-context.xml 에 추가적인 설정이 필요하다.

<mybatis-spring:scan> 태그의 base-package 속성은 지정된 패키지의 모든 MyBatis 관련 어노테이션을 찾아서 처리한다.

Mapper 테스트

MyBatis-Spring은 mapper 인터터페이스를 이용해서 실제SQL 처리가 되는 클래스를 자동으로 생성한다.

콘솔창에서 쿼리 출력을 확인할 수 있다.

XML 매퍼와 같이 쓰기

xml파일 생성

DTD와 스키마?

TimeMapper.xml 작성할때는 DTD나 스키마를 가지고 있어야 한다.

DTD를 위와같이 선언하지 않고 코드를 실행하면 DOCTYPE를 매핑시키지 못했다는 오류가 발생한다.

Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 50; Document root element "mapper", must match DOCTYPE root "null".

DTD를 작성한 후에는 아래와 같이 TimeMapper의 쿼리들이 정상적으로 실행됨을 확인할 수 있다.


log4jdbc-log4j2 설정

pom.xml에 depency추가 후 적용 확인

로그설정파일 추가하기

src/main/resources 밑에 log4jdbc.log4j2.properties 파일을 추가한다.
(일반 파일 General>File)

쿼리가 어떤식으로 연결되고 실행되는지 출력을 해주는 역할을 한다.

JDBC 연결정보 수정하기

log4jdbc를 이용하는 경우는 JDBC 드라이버와 URL 정보를 수정해야 한다. root-context.xml의 일부를 수정한다.
쿼리를 확인할 수 있도록 하려면 기존의 JDBC가 아닌 log4jdbc로 변경한다.
oracle하고 direct로 붙는 것이 아닌 Log4jdbc을 이용하고 그에 따라 클래스와 프로토콜을 수정하는 것이다.

❌ 오류발생시 클래스가 위치하는 경로 확인

properties 파일의 경로를 잘못 지정했더니 오류가 발생했다.
src/main/resouces가 아닌 src/test/resources에 생성하니
다음과 같은 오류가 발생했다.

PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.NoClassDefFoundError: Unable to find Log4j2 as default logging library. Please provide a logging library and configure a valid spyLogDelegator name in the properties file.

PropertyAccessException 오류와 함께 나타난 메시지를 분석하면, 두 가지 주요 문제점을 확인할 수 있습니다.

  1. Property 'driverClassName' threw exception;

    • 여기서 'driverClassName'이라는 프로퍼티가 예외를 발생시켰습니다. 이는 Spring 환경에서 데이터베이스 연결을 설정할 때, JDBC 드라이버의 클래스 이름을 지정하는 부분에서 발생하는 오류일 수 있습니다. 사용하려는 데이터베이스의 JDBC 드라이버가 classpath에 포함되어 있지 않을 수 있습니다.
  2. java.lang.NoClassDefFoundError: Unable to find Log4j2 as default logging library. Please provide a logging library and configure a valid spyLogDelegator name in the properties file.

    • 이 메시지는 Log4j2 로깅 라이브러리를 찾을 수 없다는 것을 나타냅니다. 프로젝트에서는 Log4j2를 기본 로깅 라이브러리로 사용하려고 했지만, 해당 라이브러리가 classpath에 존재하지 않습니다. 또한 올바른 spyLogDelegator 이름을 properties 파일에 설정하라는 메시지도 포함되어 있습니다. 이 부분은 P6Spy와 같은 라이브러리와 관련된 것 같습니다.

어디서 오류가 발생하는지 정확히 알려면 스택 트레이스나 추가적인 코드/환경 설정 정보가 필요합니다. 그러나 기반 정보만으로는 다음과 같은 점검 항목을 제안할 수 있습니다:

  1. pom.xml 또는 build.gradle 파일에서 사용하는 데이터베이스 JDBC 드라이버 라이브러리가 제대로 포함되어 있는지 확인합니다.
  2. Log4j2 라이브러리가 프로젝트의 의존성에 제대로 포함되어 있는지 확인합니다.
  3. P6Spy 또는 관련 라이브러리 설정에서 spyLogDelegator 프로퍼티가 올바르게 설정되어 있는지 확인합니다.

이러한 항목들을 점검하고 필요한 라이브러리나 설정을 추가/수정하여 문제를 해결할 수 있습니다.


설정을 변경한 후 기존의 테스트 코드를 실행하면 이전과는 달리 JDBC와 관련된 로그들이 출력되는 것을 볼 수 있다.

0개의 댓글