본문 바로가기
Back-End/Spring

Spring Boot + Gradle + MyBatis 설정

by 어렵다어려웡 2021. 7. 5.

사실 Mybatis 설정은 요근래 처음하는건데 보통은 Spring 레거시 프로젝트에서 썼던 프레임워크고

 

Spring Boot로는 보통 JPA를 많이 사용하는 추세이니 이것으로 개발을 주로하곤 한다.

 

근래 면접을 보았던 회사에서 MyBatis를 사용하신다고 하였고,

 

JPA에 비해 조금 더 추가적인 설정이 필요하다보니 설정 방법을 알아보면 괜찮을거 같기도해서 써봄.

 

개발환경은 다음과 같다.

Spring Boot 2.4.5

Gradle 7.x

MyBatis 

 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

	// 선언해야 테스트코드에서 사용가능
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
}

 

 

프로젝트 패키지

 

 

- application.properties

// application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=

spring.thymeleaf.cache=false

우선 간단하게 application.properties 파일에 DB관련 설정을 추가해줍니다.

Spring Boot는 이렇게 DB설정만 해줘도 알아서 SqlSessionFactory, 커넥션 풀 같은 설정을 스스로 맞춰줍니다.

그래서 원래는 추가적인 설정이 필요없이 개발이 가능합니다.

 

MyBatis 설정의 경우 2가지 방식으로 세팅이 가능합니다.

1. 특정 클래스 작성을 통한 방법

2. application.properties를 이용하는 방법

 

1. 특정 클래스를 작성하는 방법은 다음과 같다.

// application.properties 설정 대신 좀더 상세한 설정을 위한 config
@Configuration
@Lazy
//@EnableTransactionManagement
@RequiredArgsConstructor
@MapperScan(basePackages = "com.example.exdocker1.mapper")
public class MybatisConfig {

    private final ApplicationContext context;

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {

        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();

        sessionFactory.setDataSource(dataSource);
//        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        sessionFactory.setMapperLocations(
        context.getResources( // 1
                // 실제 쿼리가 들어갈 xml 패키지 경로
                "classpath:/mapper/*.xml"
        ));

        // Value Object를 선언해 놓은 package 경로
        // Mapper의 result, parameterType의 패키지 경로를 클래스만 작성 할 수 있도록 도와줌.
        sessionFactory.setTypeAliasesPackage( "com.example.exdocker1.domain" );
        return sessionFactory.getObject();
    }

    // Mybatis Template
    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
        
        sqlSessionTemplate.getConfiguration().setMapUnderscoreToCamelCase(true);
        
//        sqlSessionTemplate.getConfiguration().setUseGeneratedKeys(true);
        return sqlSessionTemplate;
    }

    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

1.1 @Lazy, @EnableTransactionManagement

아직 이 두가지 어노테이션의 사용 의도는 알지 못했지만, 사용하지 않아도 작동은 한다.

@Lazy의 경우 MSA 방식의 개발을 할 경우 사용한다 라는 정도로 알고 있다.

 

1.2 @MapperScan

Mybatis를 이용하여 불러올 메서드가 선언된 인터페이스의 경로를 입력합니다.

패키지상에서 봤을때 com.example.exdocker1.mapper 패키지를 통해 관리하므로 해당 패키지경로를 입력했습니다.

 

1.3 SqlSessionFactroy 메소드

public class MybatisConfig {

	// 2-1
    private final ApplicationContext context;

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {

        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();

        sessionFactory.setDataSource(dataSource); // 1 
        
        // 2-1
//      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        sessionFactory.setMapperLocations(
        context.getResources( //  2 
                "classpath:/mapper/*.xml"
        ));

        sessionFactory.setTypeAliasesPackage( "com.example.exdocker1.domain" ); // 3
        return sessionFactory.getObject();
    }

}

1번 작업 - sessionFactory.setDataSource(dataSource)

@Configuration을 통해서 DB를 통한 연결을 해당 클래스에서 하게됩니다 

따라서 직접 빈설정을 통해서 DataSource를 연결하게 됩니다.

 

2번 작업 

코드상는 ApplicationContext를 통해서 Mapper 쿼리를 읽어올 파일의 경로를 지정해주고있다.

하지만 PathMatchingResourcePatternResolver 또한 같은 역할을 하는데 두 인터페이스와 클래스는

경로를 설정할 때 차이가 있다.

 

	// 방법 1 
	PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        // 오른쪽에 있는 리소스 경로에 들어감(src/main/resources)
        sessionFactory.setMapperLocations(resolver.getResources(
                // 실제 쿼리가 들어갈 xml 패키지 경로
                "/mapper/*.xml"
        ));
        // 방법 2
        private final ApplicationContext context;
        
        sessionFactory.setMapperLocations(resolver.getResources(
              // 실제 쿼리가 들어갈 xml 패키지 경로
              "classpath:/mapper/*.xml"
        ));

경로 설정시 시작하는 경로의 차이가 있음. 

 

 

2. application.properties를 이용한 방법

이 방법 같은 경우 실무에서는 사용하지 않을 것처럼 보인다. 그 만큼 설정에 필요한 코드가 적기떄문에

간단하게 적용시켜서 개발을 시작하기 위해서 사용할 것 같다.

 

2-1 application.properties 

이렇게 SQL 쿼리를 작성하려는 파일이 있는 경로를 지정해줍니다.

// application.properties
mybatis.mapper-locations=classpath:/mapper/*.xml

2-2 Mapper Interface

입력한 Mapper 인터페이스에 @Mapper 를 선언하여 사용하면 된다.

@Mapper
public interface TestMapper {

    public String getTime();

    public int insert(TestDomain testDomain);

    public List<TestDomain> getList();
    
}

 

Mybatis는 XML 방식말고 직접 Mapper 인터페이스의 메서드에 어노테이션을 입력하여 사용하는 방식도 있으나

우선은 XML방식으로 사용했을 때 설정하는 방법을 썻다.

 

하지만 어노테이션 방식으로 했을 떄 어떤 코드를 수정해야할지 짐작이 가긴하지만 우선은 이정도로 쓰고 마친다..