[PF/PlayAsset] WebFlux R2dbc MySQL INSERT 구현 및 샘플코드

    728x90
    반응형

    2023.03.12

    개발환경구성

    - FE: React-Native

    - BE: WebFlux

    - DB: MySQL, Redis

    - IDE: Android Studio, SpringBoot(2.7.3)

    - JDK: 11

    - SERVER: AWS

     

     

    Entity

    import org.springframework.data.relational.core.mapping.Table;
    import lombok.Data;
    
    @Data
    @Table(name="테이블명(대소문자 구분)")
    public class 엔티티클래스명 {
        private Long num;
        private String str;
        private String regId;
    }

    1) SELECT가 아닌 다른 DML들은 엔티티클래스명으로 테이블에 접근

    2) 이 때, Entity에 @Table 어노테이션을 사용하면 name 속성에 입력한 테이블에 접근 가능

     

     

    Handler 구현 및 샘플코드

    import java.util.HashMap;
    import java.util.Map;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.MediaType;
    import org.springframework.stereotype.Component;
    import org.springframework.web.reactive.function.BodyInserters;
    import org.springframework.web.reactive.function.server.ServerRequest;
    import org.springframework.web.reactive.function.server.ServerResponse;
    
    import lombok.NonNull;
    import reactor.core.publisher.Mono;
    
    @Component
    public class InsertHandler {
    
        private final InsertSvc insertSvc;
    
        @Autowired
        public InsertHandler(@NonNull InsertSvc insertSvc) {
            this.insertSvc = insertSvc;
        }
    
        private Logger logger = LoggerFactory.getLogger(KeywordHandler.class);
    
        public Mono<ServerResponse> insertToMySQLViaR2dbc(ServerRequest request) {
            logger.info("========== insertToMySQLViaR2dbc START ==========");
    
            Mono<Long> count = insertSvc.insertToMySQLViaR2dbc();
            return count.flatMap(cnt->{
                return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(cnt));
            });
        }
    }

    1) 비동기로 처리되므로 flatMap을 사용해 결과를 Mono<>로 리턴

    2) Handler는 SELECT와 구조가 비슷함

     

     

    Service 구현 및 샘플코드(다건/단건)

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @Service
    public class InsertSvc {
    
        @Autowired
        private InsertDao insertDao;
    
        private Logger logger = LoggerFactory.getLogger(KeywordSvc.class);
    
        public Mono<Long> insertToMySQLViaR2dbc() {
    
            List<Entity> insertList = new ArrayList<>();
            Entity entity = new Entity();
            entity.setNum(1);
            entity.setStr("문자열01");
            insertList.add(entity);
    
            entity = new Entity();
            entity.setNum(2);
            entity.setStr("문자열02");
            insertList.add(entity);
    
            /*
             * @Desc
             * 다건 INSERT
             */
            return InsertDao.saveAll(insertList)
            .doOnError(exception -> { /* ERROR 발생 시 throw */
                logger.error("Insert failed", exception);
                throw new RuntimeException(exception);
            }).count()
            .doOnSuccess(count->{ /* INSERT Query 수행 */
                logger.info("Inserted Count : " + count);
            });
        }
    }
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    @Service
    public class InsertSvc {
    
        @Autowired
        private InsertDao insertDao;
    
        private Logger logger = LoggerFactory.getLogger(KeywordSvc.class);
    
        public Mono<Entity> insertToMySQLViaR2dbc() {
    
            List<Entity> insertList = new ArrayList<>();
            Entity entity = new Entity();
            entity.setNum(1);
            entity.setStr("문자열01");
            insertList.add(entity);
    
            /*
             * @Desc
             * 단건 INSERT
             */
            return keywordDao.save(new StockKeywordEntity()).doOnSuccess(cnt -> logger.info("Inserted Count : " + cnt));
        }
    }

    1) INSERT는 @Query 어노테이션을 사용하지 않고, ReactiveCrudRepository 인터페이스에서 상속받은 인터페이스를 그대로 사용

    2) 다건 INSERT는 saveAll 메소드를 사용하고 파라미터는 Iterator를 사용

    3) 엔티티에 사용한 필드는 테이블의 컬럼이 되고 @Table 어노테이션의 name은 테이블명이 되어 쿼리를 완성

    4) INSERT INTO TABLE_01 SET (num, str) VALUES (1, "문자열01");

     

     

    Dao 구현 및 샘플코드

    import java.util.List;
    
    import org.springframework.data.r2dbc.repository.Query;
    import org.springframework.data.repository.reactive.ReactiveCrudRepository;
    import org.springframework.stereotype.Repository;
    import reactor.core.publisher.Flux;
    
    @Repository
    public interface InsertDao extends ReactiveCrudRepository<Entity, Long> {
    }

    1) implements를 사용해 인터페이스를 굳이 구현할 필요가 없음

    2) ReactiveCrudRepository 인터페이스의 메소드를 그대로 사용한 것이므로 메소드를 추가할 필요가 없음

     

    728x90
    반응형

    댓글