본문 바로가기
  • 개발하는 곰돌이
Development/Spring & Spring Boot

[Oracle] Spring Boot 프로젝트에서 Mybatis 세팅하기 with Kotlin

by 개발하는 곰돌이 2022. 12. 20.

목차


    기본 환경

    • IntelliJ Ultimate 2022.3
    • Spring Boot 2.7.6
    • Kotlin 1.7.21(JDK 11)
    • Oracle 11g
    • Swagger 3.0.0
    • mybaitis 2.3.0
    Spring Boot 프로젝트에 Swagger 3.0.0을 적용하는 방법은 아래 포스트를 참고하면 된다.

    2022.12.06 - [Spring Boot] - Kotlin 기반 Spring Boot 프로젝트에 Swagger 3.0.0 적용하기


    Mybatis는 무엇인가?

    Mybatis는 Java에서 관계형 데이터베이스를 사용하는 개발을 더욱 수월하게 해주는 프레임워크로, 기존의 JDBC를 사용한 코드를 별도의 XML 파일로 분리하여 자바 코드상의 SQL을 모두 제거하고 관리를 편하게 해준다는 장점을 갖는다. Kotlin은 Java와 100% 호환이 가능하기 때문에 Mybatis 역시 사용할 수 있다. 본 포스트에서는 Kotlin 기반의 Spring Boot 프로젝트에 Mybatis를 적용하여 SQL 문을 실행시켜보는 예제를 다룬다.


    1. Gradle 의존성 목록에 관련 라이브러리 추가

    Mybatis를 사용하기 위해선 관련 라이브러리를 추가해야한다. Gradle 파일의 dependencies 블록 내부에 아래 코드를 추가한다.

    implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.0")
    implementation("com.oracle.ojdbc:orai18n:19.3.0.0")
    runtimeOnly("com.oracle.database.jdbc:ojdbc8")

    2. 데이터베이스 연결 설정

    src/main/resources/application.properties 파일을 열고 다음 오라클 접속 정보를 추가한다.

    # Oracle Connection Settings
    spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
    spring.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl
    spring.datasource.username=(DB 계정 명)
    spring.datasource.password=(DB 패스워드)

    여기서 spring.datasource.url, spring.datasource.username, spring.datasource.password 필드는 본인의 설정에 맞게 입력해주면 된다.


    3. Mybatis 기본 설정

    마찬가지로 src/main/resources/application.properties 파일을 열고 다음 항목을 추가한다.

    # Mapper Location
    mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
    
    # Domain Aliases
    mybatis.type-aliases-package=com.colabear754.mybatis_example.domain
    
    # JDBC null settings
    mybatis.configuration.jdbc-type-for-null=null

    각 항목에 대한 설명은 다음과 같다.

    • mybatis.mapper-locations : Mybatis에서 사용할 Mapper 파일의 경로. 위의 경우에는 resources/mapper 폴더에서 Mapper.xml로 끝나는 모든 파일을 읽어들인다.
    • mybatis.type-aliases-package : DTO, VO 등의 도메인 클래스가 포함된 패키지 경로. 필수 사항은 아니지만 이 항목을 설정하지 않으면 mapper 파일에서 DTO, VO를 사용할 때 패키지 경로를 모두 작성해야 한다.
    • mybatis.configuration.jdbc-type-for-null : Mybatis의 SQL 문에 null을 파라미터로 전송할 수 있게 해준다.

    4. Mapper 인터페이스 작성

    mapper 패키지 내부에 BoardMapper 인터페이스를 생성하여 @Mapper 어노테이션을 인터페이스 위에 붙이고 다음과 같이 작성한다. 본 포스트에서는 간단하게 게시판의 글들을 가져오는 메소드만 작성한다.

    package com.colabear754.mybatis_example.mapper
    
    import com.colabear754.mybatis_example.domain.BoardDTO
    import org.apache.ibatis.annotations.Mapper
    
    @Mapper
    interface BoardMapper {
        fun getDocuments(): List<BoardDTO>
    }

    5. Mapper.xml 작성

    /src/main/resources 폴더 내부에 위에서 mybatis.mapper-locations에 설정한 이름의 폴더를 생성하고 BoardMapper.xml 파일을 생성하고 아래와 같이 작성한다. 이 예제에서는 /src/main/resources/mapper에 해당한다. namespace의 값은 4번 단계에서 생성한 인터페이스 파일의 경로를 입력한다.

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
    <mapper namespace="com.colabear754.mybatis_example.mapper.BoardMapper">
    
    </mapper>

    Mapper.xml을 작성했다면 mapper 태그 내부에 쿼리문을 작성하면 된다. 멤버들의 아이디를 가져올 것이니 mapper 태그 내부에 해당 쿼리를 작성한다. id에는 4번 단계에서 작성한 인터페이스의 메소드 이름을 그대로 작성하면 되고, resultType에는 반환받을 타입을 작성한다.

    <select id="getDocuments" resultType="BoardDTO">
        select *
        from BOARD
    </select>

    최종적인 BoardMapper.xml의 모습은 다음과 같다.

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
    <mapper namespace="com.colabear754.mybatis_example.mapper.BoardMapper">
        <select id="getDocuments" resultType="BoardDTO">
            select *
            from BOARD
        </select>
    </mapper>

    6. DTO 클래스 작성

    5번 단계에서 작성한 Mapper.xml의 select 쿼리에 반환타입을 일반적인 변수 타입이 아닌 객체 타입으로 지정했다면 그에 맞는 DTO 클래스를 작성한다. 본 예제에서는 BoardDTO를 작성한다.

     

    위의 application.properties에서 mybatis.type-aliases-package에 설정한 패키지 경로에 BoardDTO를 작성한다. 이 내용은 필자의 DB 내용이므로 각자 설정에 맞게 수정하면 된다. @JsonFormat은 날짜 형식을 위해 붙여준 어노테이션이다.

    package com.colabear754.mybatis_example.domain
    
    import com.fasterxml.jackson.annotation.JsonFormat
    import java.time.LocalDateTime
    
    data class BoardDTO(
        var seq: Int,
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        var reg_time: LocalDateTime,
        var subject: String,
        var content: String,
        var view_cnt: Int,
    )

    7. 컨트롤러 작성

    이제 마지막으로 컨트롤러를 작성한다. 기본 패키지 내부에 controllers 패키지를 생성하여 BoardController를 작성한다.

    package com.colabear754.swagger_example.controllers
    
    import com.colabear754.swagger_example.mapper.BoardMapper
    import io.swagger.annotations.Api
    import io.swagger.annotations.ApiOperation
    import org.springframework.web.bind.annotation.GetMapping
    import org.springframework.web.bind.annotation.RestController
    
    @Api(tags = ["게시판 글 API"], description = "게시판 글을 다루는 API")
    @RestController
    class BoardController(private val boardMapper: BoardMapper) {
        @ApiOperation(value = "게시글 목록 조회", notes = "모든 게시글 목록을 조회합니다.")
        @GetMapping("/document-list")
        fun document_list() = boardMapper.getDocuments()
    }

    Kotlin에서는 빈을 주입할 때 생성자가 하나뿐일 경우엔 @Autowired를 생략하고 기본 생성자의 파라미터로 작성할 수 있다. 만약 기본 생성자를 사용하지 않고 @Autowired를 사용하고 싶다면 아래와 같이 작성하면 된다.

    class BoardController {
        @Autowired
        private lateinit var boardMapper: BoardMapper
        
        ...
    }

    8. 실행 결과

    모든 과정이 끝났다면 Shift+F10을 눌러 프로젝트를 실행하고 브라우저의 주소창에 http://localhost:8080/swagger-ui/index.html를 입력하여 스웨거 API 문서에서 테스트를 해볼 수 있다.

     

    주소창에 http://localhost:8080/document-list를 입력해도 결과를 확인할 수 있다.

    결과가 정상적으로 나타나는 것을 볼 수 있다.

    댓글