OS: Windows 11
IDE: IntellJ IDEA 2022.2.4 (Ultimate Edition)
Java: 1.8
Framework: Springframework.boot version: 2.4.3
WebFlux라는 거 자체도 힘들었는데 왜... 쉬운게 하나도 없는거니
JPA는 기본적으로 비동기를 제공하지 않는다.
Webflux 모듈은 기본적으로 비동기 non-blocking 방식을 지원하는데 JPA를 사용하면 Database 부분에서 block되고, 그동안 thread가 기다리게 된다.
참고 - R2DBC를 사용해보자 (1) - 왜 사용할까?
그래서 울며 겨자먹기로 R2D2를 사용함.
고생 깨나 함. 시행착오를 겪는 과정이기 때문에 틀린 내용이 있을 수 있음.
implementation "org.springframework.boot:spring-boot-starter-data-r2dbc"
implementation 'com.github.jasync-sql:jasync-r2dbc-mysql:2.1.7'
implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'
spring:
r2dbc:
url: r2dbc:pool:mysql://127.0.0.1:3306/fruit
username: armton
password: 비밀번호~
import lombok.*;
import org.springframework.data.annotation.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import javax.persistence.*;
@Table(name = "fruit_entity") // R2D2에선 인식 X
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@Getter
@Setter
public class FruitEntity {
@Id
@Column(name = "NAME")
private String name;
@Column(name = "TYPE")
private String type;
@Column(name = "CREATE_DATE")
@CreatedDate
private String createDate;
@Column(name = "UPDATE_DATE")
@LastModifiedDate
private String updateDate;
@Transient
private String errorCode;
@Transient
private String errorMessage;
}
JPA와 비슷한듯 뭔가 다른 엔티티 구성
@Id,
@Transient
어노테이션은 org.springframework.data.annotation
★★★@Table
에 name으로 테이블 명을 지정해줘도 반영이 안 됨. 카멜표기법 클래스명으로만 인식함.@CreatedDate
딱히 안 먹힘** 참고로 지금 나는 여기서 @Id
를 String
으로 선언했다. R2D2는 Update 시 Long
형의 Id만 인지함. 이렇게 String
로 하면 Persistable
을 구현하고 isNew()
를 재정의해도 반영되지 않음.
import com.armton.r2d2.model.FruitEntity;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import reactor.core.publisher.Mono;
public interface FruitRepository extends R2dbcRepository<FruitEntity, String> {
// 커스텀 메소드 생성 예시
// Mono나 Flux 타입으로 받아야 함.
Mono<FruitEntity> findByName(String name);
Mono<Void> deleteByName(String name);
}
ReactiveCrudRepository
를 받았는데 이걸로 하면 bean 생성을 못 함.~Repository bean not found
→ application클래스에 @EnableR2dbcRepositories("com.armton.r2d2.repository")
이걸 달아줬는데도 못 찾음 → R2dbcRepository
로 바꿔줬더니 됨.@Service
RegisterService.java
private final FruitClient fruitClient;
public Mono<String> registerFruit(Register register) throws CustomException {
return fruitClient.insertFruit(
FruitEntity.builder()
.name(register.getName())
.type(register.getType())
.build()).log()
.flatMap(check -> {
if(check){
return Mono.just(OK);
}else{
throw new CustomException(FAILED_INSERT_FRUIT);
}
});
}
@Service
FruitClient.java
private final FruitRepository fruitRepository;
@Autowired
public FruitClient(FruitRepository fruitRepository) {
this.fruitRepository = fruitRepository;
}
public Mono<Boolean> insertFruit(FruitEntity fruitEntity) {
try {
fruitRepository.save(fruitEntity).subscribe();
return Mono.just(true);
}catch (Exception e){
e.printStackTrace();
return Mono.just(false);
}
}