Micronaut + Kotlin 프로젝트에서 MyBatis를 사용하여 데이터베이스에 데이터를 등록하십시오.

지난번



Micronaut + Kotlin 프로젝트에서 MyBatis를 사용하여 데이터베이스에서 데이터를 검색하십시오.

이전 프로젝트를 확장하고 데이터베이스에 데이터를 등록하고 싶습니다.
실제로 만든 리포지토리는 여기입니다.

Mapper



인터페이스 만들기



BookMapper.kt에 다음 메서드의 선언을 추가합니다.
  • insert : 데이터 등록 (Insert 문 실행)을 수행합니다.
  • update : 데이터 업데이트 (Update 문 실행)를 수행합니다.

  • server/src/main/kotlin/example/mapper/BookMapper.kt
    package example.mapper
    
    import example.model.Book
    import org.apache.ibatis.annotations.Mapper
    
    @Mapper
    interface BookMapper {
        fun findAll(): List<Book>
        fun findById(id: Int): Book
        fun insert(book: Book)
        fun update(book: Book)
    }
    

    SQL 만들기



    실행할 SQL 본문을 정의합니다.
    이 샘플에서는 BookMapper.xml에 정의합니다.

    server/src/main/resources/example/mapper/BookMapper.xml
        <insert id="insert" parameterType="example.model.Book">
            INSERT INTO book (
                name,
                publisher,
                publication_date,
                created_at,
                updated_at
            ) VALUES (
                #{name},
                #{publisher},
                #{publicationDate},
                current_timestamp,
                current_timestamp
            );
        </insert>
    
        <update id="update" parameterType="example.model.Book">
            UPDATE book
            SET
                name = #{name},
                publisher = #{publisher},
                publication_date = #{publicationDate},
                updated_at = current_timestamp
            WHERE
                id = #{id}
        </update>
    

    구현 부분 만들기



    구현 부분으로서 Service 클래스에도 메소드를 추가합니다.
  • insert(book: Book)
  • update(book: Book)

  • server/src/main/kotlin/example/service/BookService.kt
    package example.service
    
    import example.mapper.BookMapper
    import example.model.Book
    import org.apache.ibatis.session.SqlSessionFactory
    import javax.inject.Singleton
    
    @Singleton
    class BookService(private val sqlSessionFactory: SqlSessionFactory) : BookMapper {
    
        override fun findAll(): List<Book> {
            sqlSessionFactory.openSession().use { session ->
                val bookMapper = session.getMapper(BookMapper::class.java)
                return bookMapper.findAll()
            }
        }
    
        override fun findById(id: Int): Book {
            sqlSessionFactory.openSession().use { session ->
                val bookMapper = session.getMapper(BookMapper::class.java)
                return bookMapper.findById(id)
            }
        }
    
        override fun insert(book: Book) {
            sqlSessionFactory.openSession().use { session ->
                val bookMapper = session.getMapper(BookMapper::class.java)
                bookMapper.insert(book)
                session.commit()
            }
        }
    
        override fun update(book: Book) {
            sqlSessionFactory.openSession().use { session ->
                val bookMapper = session.getMapper(BookMapper::class.java)
                bookMapper.update(book)
                session.commit()
            }
        }
    
    }
    

    컨트롤러



    데이터베이스에 액세스하는 API를 작성합니다.
    Mapper와 마찬가지로 등록 및 업데이트를 위한 입을 만듭니다.
  • create(book: Book) : 등록용 API. /book POST로 요청하여 실행.
  • update(book: Book) : 업데이트용 API. /book PUT에서 요청하여 실행.

  • server/src/main/kotlin/example/controller/BookController.kt
    package example.controller
    
    import example.mapper.BookMapper
    import example.model.Book
    import io.micronaut.http.HttpResponse
    import io.micronaut.http.annotation.Controller
    import io.micronaut.http.annotation.Get
    import io.micronaut.http.annotation.Post
    import io.micronaut.http.annotation.Put
    
    
    @Controller()
    class BookController(private val bookMapper: BookMapper) {
    
        /**
         * 書籍情報の全取得。
         *
         * @return HttpResponse
         */
        @Get("/book")
        fun read(): HttpResponse<List<Book>> {
            return HttpResponse.ok(bookMapper.findAll())
        }
    
        /**
         * 書籍情報の取得。
         * ID指定
         *
         * @param id 書籍ID
         *
         * @return HttpResponse
         */
        @Get("/book/{id}")
        fun readById(id: Int): HttpResponse<Book> {
            return HttpResponse.ok(bookMapper.findById(id))
        }
    
        /**
         * 書籍情報の登録。
         */
        @Post("/book")
        fun create(book: Book): HttpResponse<String> {
            bookMapper.insert(book)
            return HttpResponse.ok()
        }
    
        /**
         * 書籍情報の更新。
         */
        @Put("/book")
        fun update(book: Book): HttpResponse<String> {
            bookMapper.update(book)
            return HttpResponse.ok()
        }
    }
    

    모델



    모델도 약간 수정합니다.
    마지막으로 JSON이 일부 항목에서 올바르게 매핑되지 않았기 때문에 JsonProperty 어노테이션을 추가합니다.

    server/src/main/kotlin/example/model/Book.kt
    package example.model
    
    import com.fasterxml.jackson.annotation.JsonProperty
    import io.micronaut.core.annotation.Introspected
    import java.sql.Date
    
    
    /**
     * 書籍データクラス
     */
    @Introspected
    data class Book(
            @JsonProperty("id")
            var id: Int?,
    
            @JsonProperty("name")
            var name: String,
    
            @JsonProperty("publisher")
            var publisher: String?,
    
            @JsonProperty("publication_date")
            var publicationDate: Date?,
    )
    

    일단 완성



    지금까지 책 정보를 등록, 갱신하는 API가 작성되었습니다.
    시도해 봅시다.

    서버를 실행합니다.
    $ cd server 
    $ ./gradlew run
    

    이번 API에 대한 요청에는 POSTMAN을 사용합니다.

    먼저 등록해 보겠습니다.


    돈!


    등록할 수 있었습니다!

    그런 다음 업데이트를 시도합니다.nametest書籍3로 설정합니다.

    돈!

    업데이트할 수 있었습니다!

    결론



    이번에 추가한 insertupdateBookService 안에서 각 SQL 실행 후에 session.commit()를 하고 있습니다.
    참고로 한 가이드 에서도 똑같이 각 SQL의 실행 후에 session.commit()를 실행해 트랜잭션(transaction)를 확정시키고 있습니다.
    다만, 개인적으로는 메소드 단위로 트랜잭션을 확정시키는 것은 쓰기가 나쁜 것처럼 느낍니다.
    예를 들면, 실업무로 개발하는 서비스에서는 1 리퀘스트 중에서 복수의 테이블 갱신도 하는 일이 있을까 생각합니다.
    가능하면 API 단위로 트랜잭션을 갖고 싶은 곳입니다.
    Spring Boot라고 기사를 찾을 수 있지만, Micronaut이라면 어떻게 할 것이라고 조사 중. .

    다음에 하고 싶은 일


  • DB 주위의 자동 테스트를 만들고 싶습니다. 무엇을 사용하는 것이 사실입니까?
  • React 공부하기 시작했기 때문에, 프런트 만들어 보자.

  • 참고


  • Access a database with MyBatis
  • 좋은 웹페이지 즐겨찾기