본문으로 바로가기

[Spring Boot] MyBatis 사용법 (@Mapper, @MapperScan)

category Backend/Spring 2021. 11. 20. 13:55

목차

    0. 환경

    • windows10
    • openjdk version "11" 2018-09-25
    • IntelliJ Tool
    • Spring Boot 2.5.6
    • Gradle Project 
    • MyBatis + Mysql + HikariCP를 이용해 DB(Mysql) 연동할 프로젝트입니다.

    1. 도메인 생성

    • 데이터를 주고받을 때 사용할 도메인을 생성합니다.
    • com/test/api/domain/Test.java

    [기본]

    package com.test.api.domain;
    
    public class Test {
    
        private String column1;
        private String column2;
    
        public String getColumn1() {
            return column1;
        }
    
        public String getColumn2() {
            return column2;
        }
    
        public void setColumn1(String column1) {
            this.column1 = column1;
        }
    
        public void setColumn2(String column2) {
            this.column2 = column2;
        }
    }

     

    [lombok 사용]

    • 사용 전 인텔리제이 초기 설정
    • File > Settings(preference) > Build, Execution, Deployment > Compiler > Annotation Processors

    package com.test.api.domain;
    
    import lombok.Getter;
    import lombok.Setter;
    
    @Getter
    @Setter
    public class Test {
    
        private String column1;
        private String column2;
    }

    2. Mapper Interface 생성

    • Mapper 설정 파일(xml)에 있는 SQL 쿼리문을 호출하기 위한 인터페이스를 생성합니다.
    • DAO 대신 @Mapper 어노테이션을 사용합니다. (mybatis 3.0 이상)
    • @Mapper 어노테이션을 사용하면 빈으로 등록되며 Service단에서 Autowired 하여 사용할 수 있습니다.
    • 메소드 명은 Mapper xml 파일의 id와 맞춰줘야 합니다.
    • @Mapper 가 아닌 @MapperScan 어노테이션을 이용할 수도 있습니다. 
    • com/test/api/mapper/TestMapper.java
    package com.test.api.mapper;
    
    import com.test.api.domain.Test;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface TestMapper {
        Test test() throws Exception;
    }

     

    [@MapperScan 사용 시]

    • DB 설정 클래스 파일에 @MapperScan(value="매퍼 인터페이스 경로")를 추가해 줍니다.
    package com.test.api.config;
    
    import com.zaxxer.hikari.HikariConfig;
    import com.zaxxer.hikari.HikariDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    
    import javax.sql.DataSource;
    
    @Configuration
    @PropertySource("classpath:/application.properties")
    @MapperScan(value="com.test.api.mapper")
    public class DBConfig {
    
        private final ApplicationContext applicationContext;
    
        @Autowired
        DBConfig(ApplicationContext applicationContext){
            this.applicationContext = applicationContext;
        }
    
        @Bean
        @ConfigurationProperties(prefix="spring.datasource.hikari")
        public HikariConfig hikariConfig() {
            return new HikariConfig();
        }
    
        @Bean
        public DataSource dataSource() throws Exception {
            DataSource dataSource = new HikariDataSource(hikariConfig());
            return dataSource;
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
            sqlSessionFactoryBean.setTypeAliasesPackage("com.test.api.domain");
            sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/*.xml"));
            return sqlSessionFactoryBean.getObject();
        }
    
        @Bean
        public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

     

    [Mapper Interface]

    package com.test.api.mapper;
    
    import com.test.api.domain.Test;
    import org.mybatis.spring.annotation.MapperScan;
    
    @Component
    @MapperScan
    public interface TestMapper {
        Test test() throws Exception;
    }

    3. Mapper xml 생성

    • 쿼리를 작성할 매퍼 xml을 설정 파일에 지정한 경로로 생성합니다.
    • mapper namespace 값을 Mapper Interface와 맞춰 줍니다.
    • id는 Mapper Interface 클래스에서 선언한 메서드의 이름과 동일하게 맞춰줍니다.
    • resources/mapper/TestMapper.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.test.api.mapper.TestMapper">
    
        <select id="test" parameterType="map" resultType="Test">
            SELECT 1 AS 'column1', 2 AS 'column2'
        </select>
    
    </mapper>

    4. 서비스 생성

    • Mapper Interface를 주입받아 사용할 서비스를 생성합니다.
    • com/test/api/service/TestService.java
    package com.test.api.service;
    
    import com.test.api.domain.Test;
    import com.test.api.mapper.TestMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class TestService {
    
        private final TestMapper testMapper;
    
        @Autowired
        public TestService(TestMapper testMapper){
            this.testMapper = testMapper;
        }
    
        public Test test() throws Exception {
            return testMapper.test();
        }
    }

    5. 컨트롤러 생성

    • 테스트 및 서비스를 사용하기 위해 컨트롤러를 생성해줍니다.
    • com/test/api/controller/TestController.java
    package com.test.api.controller;
    
    import com.test.api.domain.Test;
    import com.test.api.service.TestService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
        private final TestService testService;
    
        @Autowired
        public TestController(TestService testService){
            this.testService = testService;
        }
    
        @GetMapping(value = "/test")
        public Test test() throws Exception {
            return testService.test();
        }
    
    }

    6. 테스트

    • Spring Boot를 실행 후 브라우저를 이용해 해당 컨트롤러 경로로 접속해 봅니다.

    7. 전체 구성

    • 안 될 경우 해당 그림을 보고 빠트린 부분을 확인해봅니다.