728x90

 

글을 쓰기 전에 항상 고민합니다,, 오늘은 어떤 잔망루피를 데려올까,,🥸

 

오늘은 R2DBC에서 쿼리를 작성하는 2가지 방법을 작성할 예정이기에 잔망루피 2명이 있는 짤을 데려왔습니다,,

 

잔망 루피 2명,, (+ 뒷모습의 잔망루피는 덤,,)과 함께하는 Custom Query를 정리해보고자 합니다,,

 

1. gradle.build

외부 라이브러리를 쓰기 위해 종속성을 추가해줍니다.

dependencies{
  	// r2dbc 설정
	implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc' // JDBC 대신 비동기 방식으로 DB와 통신할 수 있도록 지원
	implementation 'io.asyncer:r2dbc-mysql:1.0.2' // R2DBC를 이용해 MySQL과 연결하기 위한 드라이버
	// 비동기/리액티브 방식으로 MySQL과 데이터를 주고받을 수 있도록 하는 설정
	// 리액티브(Reactive) 방식: 비동기(Asynchronous) + 논블로킹(Non-blocking) 프로그래밍 모델
}

 

 

2. application.yml

DB 설정을 추가해줍니다.

사용 DB: MySQL🐬

spring:
  r2dbc:
    url: r2dbc:mysql://localhost:3307/database_name
    username: username
    password: passworad

 

 

 

3. R2dbcConfig.java

R2DBC 설정 파일을 만들어줍니다.

@Component
@RequiredArgsConstructor
@Slf4j
@EnableR2dbcRepositories // 리액티브 리포지토리(ReactiveCrudRepository 등)를 자동으로 스캔하고, R2DBC를 통해 사용할 수 있도록 설정
@EnableR2dbcAuditing // R2DBC 엔터티의 자동 감사(Auditing) 기능을 활성화, createdAt, updatedAt 같은 값을 자동으로 입력
public class R2dbcConfig {
  private final DatabaseClient databaseClient;
  // MySQL 연결 시, 객체 생성은 하지만 Connection까지는 보장하지 않음
  // application.properties 파일에서 비밀번호 틀려도 Spring 연결 O
 }

 

 

4-1. Custom Repository 만들기 - @Query 버전

public interface UserR2dbcRepository extends ReactiveCrudRepository<User, Long> {

  @Modifying
  // @Query: 읽기 전용(SELECT 쿼리)으로 동작
  // CREATE, UPDATE, DELETE 같은 데이터를 변경하는 쿼리를 실행하려면 @Modifying을 추가
  @Query("DELETE FROM users WHERE name = :name")
  Mono<Integer> deleteByName(String name);
}

 

 

4-2. Custom Repository 만들기 - DatabaseClient

@Repository
@RequiredArgsConstructor
public class PostR2dbcCustomRepositoryImpl implements PostR2dbcCustomRepository {
  private final DatabaseClient databaseClient;

  @Override
  public Flux<Post> findAllByUserId(Long userId) {
    String sql = """
                SELECT p.id as pid, p.user_id as userId, p.title, p.content, p.created_at as pcreatedAt, p.updated_at as pupdatedAt,
                       u.id as uid, u.name, u.email, u.created_at as ucreatedAt, u.updated_at as uupdatedAt
                FROM posts p
                LEFT JOIN users u ON p.user_id = u.id
                WHERE p.user_id = :userId
        """;

    return databaseClient.sql(sql)
                         .bind("userId", userId)
                         // :userId에 매핑 -> 오류나는 부분 IntelliJ 문제
                         .fetch()
                         // fetch().all()을 쓰면 Flux, fetch().one()을 쓰면 Mono를 반환
                         .all()
                         .map(row -> Post.builder()
                                         .id((Long) row.get("pid"))
                                         .userId((Long) row.get("userId"))
                                         .title((String) row.get("title"))
                                         .content((String) row.get("content"))
                                         .user(User.builder()
                                                   .id((Long) row.get("uid"))
                                                   .name((String) row.get("name"))
                                                   .email((String) row.get("email"))
                                                   .createdAt(((ZonedDateTime) row.get("ucreatedAt")).toLocalDateTime())
                                                   .updatedAt(((ZonedDateTime) row.get("uupdatedAt")).toLocalDateTime())
                                                   .build())
                                         .createdAt(((ZonedDateTime) row.get("pcreatedAt")).toLocalDateTime())
                                         .updatedAt(((ZonedDateTime) row.get("pupdatedAt")).toLocalDateTime())
                                         .build());
  }
}

 

 

5. Custom Repository별 장단점 정리

비교 항목 ReactiveCrudRepository DatabaseClient
특징 ReactiveCrudRepository 기본 메서드
(save, findById, deleteById 등) 사용 가능
SQL 직접 작성
유연성 @Query로 커스텀 쿼리 가능
복잡한 JOIN 처리 어려움
복잡한 JOIN 및 다양한 SQL 작성 가능
활용 기본적인 CRUD 및 간단한 조건 검색에 적합 직접 최적화가 가능하므로
복잡한 비즈니스 로직이 필요한 경우 적합
동적 쿼리 불가능(동적 쿼리 작성 시, Querydsl 필요) 가능

 

 

 

📑

참고 자료

Chat GPT

https://fastcampus.co.kr/dev_online_traffic_data

 

9개 프로젝트로 경험하는 대용량 트래픽 & 데이터 처리 완벽 마스터하기 | 패스트캠퍼스

실무에서 자주 일어나는 대용량 트래픽 & 데이터 처리 업무를 한번에 마스터할 수 있도록 모든 것을 담았습니다. 대기업 & 빅테크 현업 강사진 8인과 함께 하는 고퀄리티 현업 대비형 강의! 타사

fastcampus.co.kr

 

 

728x90