r2dbc

005 R2dbc Metadata Mapping

December 9, 2023
2023-12-09
webflux, r2dbc, mysql

05. Metadata mapping # Entity 클래스에 어노테이션을 추가 # @Id: primary key에 해당하는 필드에 적용 @Table: entity class에 적용. Table 이름을 변경 가능 @Transient: 기본적으로 모든 필드는 mapping 대상. @Transient가 붙은 필드는 mapping 에서 제외 @Column: entity의 property 필드에 적용. @Column이 붙은 필드에 대해서는 convention 기반 대신 Column에 주어진 name으로 적용 @Version: 낙관적 잠금 (Optimistic Lock)에 이용. entity가 update 될때마다 자동으로 update @PersistenceConstructor: 특정 constructor에 대해서 Object creation할 때 사용하게끔 지정. ...

006 R2dbc Entity Operations

December 9, 2023
2023-12-09
webflux, r2dbc

06. R2dbcEntityOperations # 구조 # R2dbcEntityTemplate가 R2dbcEntityOperations를 상속한다. R2dbcEntityOperations가 FluentR2dbcOperations를 상속한다. FluentR2dbcOperations는 여러 Operations를 상속한다. ReactiveSelectOperation : select query와 관련된 메서드 제공 ReactiveInsertOperation : insert query와 관련된 메서드 제공 ReactiveUpdateOperation : update query와 관련된 메서드 제공 ReactiveDeleteOperation : delete query와 관련된 메서드 제공 ReactiveSelectOperation # ReactiveSelectOperation의 select부터 시작 TerminatingSelect의 count, exists, first, one, all 등으로 종료 구조 select -> from -> as -> matching -> 실행 select -> from -> matching -> 실행 select -> as -> matching -> 실행 select -> matching -> 실행 select -> -> 실행 ReactiveSelectOperation 사용 # from : query를 실행할 table 이름을 전달 as : Entity를 전부 mapping 하지 않고 특정 필드만 mapping 하고 싶은 경우 Entity의 일부 프로퍼티만 담고 있는 subclass(혹은 인터페이스)를 넘겨서 projection projection이 제공되지 않는다면 Entity에 모든 필드를 mapping matching : query의 where문에 해당 matching을 생략하면 table 전체에 대한 요청을 보내는 것과 동일 실행 : 마지막으로 count, exists, first, one, all 등의 연산을 선택 count: 조건에 맞는 row의 개수 반환 exists: 조건에 맞는 row 존재 여부 반환 first: 조건에 맞는 첫 번째 row 반환 one: 조건에 맞는 하나의 row 반환. ...

007 R2dbc Repository

December 9, 2023
2023-12-09
webflux, r2dbc

07. R2dbcRepository # R2dbcRepository 구조 # ReactiveSortingRepository와 ReactiveQueryByExampleExecutor를 상속한 interface인 SimpleR2dbcRepository에서 구현 R2dbcRepository 등록 # R2dbcRepositoriesAutoConfiguration가 활성화되어 있다면 SpringBootApplication 기준으로 자동으로 scan 혹은 EnableR2dbcRepositories를 통해서 repository scan 만약 여러 r2dbcEntityTemplate이 존재하거나 여러 데이터베이스를 사용하는 경우, basePackages, entityOperationRef 등을 통해서 다른 경로, 다른 entityTemplate 설정 가능 Repository # Spring data에서는 Repository interface를 제공 데이터에 접근하는 계층을 추상화하고 CRUD 작업, Entity mapping, SQL 쿼리 생성 등을 자동으로 수행 ReactiveCrudRepository # Spring data reactive에서는 CrudRepository의 Reactive 버전인 ReactiveCrudRepository 지원 entity의 CRUD에 집중 모든 결과값 그리고 일부 인자들이 Publisher 지원 ReactiveCrudRepository - save # saveAll은 @Transactional을 사용해서 각각의 save를 하나의 tx로 묶고 concatMap을 통해서 save를 순차적으로 수행 ReactiveCrudRepository - find # id 기반으로 하나 혹은 여러 개의 항목을 탐색하거나 존재 여부를 확인 모든 항목을 탐색하거나 모든 항목의 개수를 확인 ReactiveCrudRepository - delete # id 기반으로 하나 혹은 여러 개의 항목을 제거하거나 하나 혹은 여러 개의 entity를 기반으로 id를 추출하여 제거하거나, 모두 제거 ReactiveSortingRepository # ReactiveCrudRepository를 상속 spring data의 Sort를 기반으로 여러 항목 탐색 Sort 객체는 여러 Order 객체를 포함 이를 기반으로 query에 sort 옵션을 제공 SimpleR2dbcRepository # R2dbcRepository를 구현 R2dbcEntityOperations를 기반으로 SQL 쿼리를 실행하고 결과를 Entity로 mapping 기본적으로 모든 메소드에 @Transactional(readOnly = true) 적용 SimpleR2dbcRepository - save # new entity 확인 전략 @Id에 해당하는 필드를 확인. ...

008 R2dbc Query Method

December 9, 2023
2023-12-09
webflux, r2dbc

08. R2dbc Query Method # 쿼리 메소드 (Query method) # R2dbcRepository를 상속한 repository interface에 메소드를 추가 메소드의 이름을 기반으로 Query 생성 조회, 삭제 지원 @Query 어노테이션을 사용해서 복잡한 쿼리나 update 문도 실행 가능 쿼리 메소드 - find # id 뿐만 아니라 다른 필드를 이용해서 조회 가능 first 등의 키워드를 사용해서 query에 limit 제공 가능 기존의 Entity 뿐만 아니라 Projection을 사용하여 일부 필드만 조회 가능 findFirstByNameOrderByAgeDesc name이 “taewoo”인 row들을 찾고 age 내림차순으로 sort 하여 limit을 1로 모든 field를 조회하여 PersonEntity class로 mapping 쿼리 메소드 - delete # 다른 필드를 이용해서 삭제 가능 여러 반환 타입 지원 Integer: 영향을 받은 row 수 반환 Boolean: 삭제되었는지 여부 반환 Void: 반환값보다는 completion이 중요한 경우 deleteByAgeGreaterThan age가 100 초과인 row를 찾고 삭제한 후 영향을 받은 row가 있다면 true를, 없다면 false를 반환 쿼리 메서드 시작 키워드 # find, read, get, query, search, stream find 쿼리를 실행하고 결과를 Publisher으로 반환 exists find exists 쿼리를 실행하고 결과를 Publisher으로 반환 count find count 쿼리를 실행하고 결과를 Publisher으로 반환 delete, remove delete 쿼리를 실행하고 Publisher 혹은 publisher로 삭제된 개수 반환 쿼리 메서드 제한 키워드 # First, Top 쿼리의 limit을 N으로 설정. ...

003 R2dbc Entity Template

December 8, 2023
2023-12-08
webflux, r2dbc, mysql

03. R2dbcEntityTemplate # Entity # 데이터베이스에서 하나의 Row와 매칭되는 클래스 R2dbcEntityTemplate, R2dbcRepository 등은 데이터베이스에 요청을 보내고 그 결과를 Entity 형태로 반환 Table, Row, Column에 필요한 데이터베이스 metadat를 어노테이션으로 제공 R2dbcEntityTemplate # Spring data r2dbc의 추상화 클래스 메서드 체이닝을 통해서 쿼리를 수행하고 결과를 entity 객체로 받을 수 있다. R2dbcEntityOperations를 구현 public class R2dbcEntityTemplate implements R2dbcEntityOperations, BeanFactoryAware, ApplicationContextAware { private final DatabaseClient databaseClient; ... } R2dbcEntityTemplate 생성 # ConnectionFactory를 제공하거나 R2dbcDialect, R2dbcConverter를 제공하여 constructor로 생성 가능 R2dbcDialect : R2dbc 버전의 Dialect 확장 R2dbcEntityTemplate 빈 등록 # R2dbcDataAutoConfiguration 위 클래스를 통해서 DatabaseClient, R2dbcDialect, MappingR2dbcConverter를 주입 @AutoConfiguration(after = R2dbcAutoConfiguration. ...

004 R2dbc Object Mapping

December 8, 2023
2023-12-08
webflux, r2dbc, mysql

04. Object mapping # Spring data의 object mapping # 만약 지원하는 converter이 없다면 MappingR2dbcConverter는 다음 과정을 거쳐서 Row를 Entity로 변환한다. Object cretion : Row의 column들로 Object 생성 Property population : direct set, setter, with..메서드 등을 이용해서 Row의 Column을 Objec에 주입 Object creation # Object creation 테스트 # R2dbcEntityTemplate의 select 호출시, R2dbcConverter를 사용하기 때문에 이를 이용해서 selet에 class를 넘기는 방식으로 테스트 PersistenceCreator constructor # @PersistenceCreator 을 갖는 constructor가 존재한다면 해당 constructor를 사용 여러개가 존재한다면 가장 마지막 @PersistenceCreator가 붙은 constructor를 사용 NoArgsConstructor, AllArgsConstructor 전부 패스 NoArgs constructor # @PersistenceCreator 을 갖는 constructor가 없는 경우 No-args constructor가 존재한다면 해당 constructor를 사용 다른 constructor 전부 패스 하나의 constructor # 오직 하나의 constructor이 존재한다면 해당 constructor 사용 2개 이상의 constructor가 있다면? ...

002 R2dbc Mysql

December 7, 2023
2023-12-07
webflux, r2dbc, mysql

02. R2dbc MySQL # R2dbc MysqlConnection # Connection을 구현한 MysqlConnection ConnectionMetadata를 구현한 MysqlConnectionMetadata Statement를 구현한 MysqlStatement MysqlConnectionFactory # Mono 형태로 포함 MysqlConnectionConfiguration을 인자로 받아서 MysqlConnectionFactory를 생성 MysqlConnectionFactory로 MysqlConnection 생성 MysqlConnection으로 MysqlStatement를 생성 MysqlConnection으로 transaction을 start, rollback, commit MysqlConnectionConfiguration # MYSQL 연결의 설정을 포함하는 객체 Builder 패턴 host, port, database, username 등 기본 설정 제공 serverZoneId 설정 MysqlConnection 생성 # Sql 준비 # Sql 실행 # ConnectionFactory의 create()를 통해서 connection 접근 connection의 createStatement를 통해서 sql 준비 result의 map으로 row에 접근하고 Person으로 변환 thenMany() chaining : 순차적으로 실행 selectPeople 결과를 아래로 전달 result의 map으로 row에 접근하고 Person으로 변환 MysqlConnection의 한계 # SQL 쿼리를 명시적으로 전달 반환된 결과를 수동으로 파싱 별도의 mapper를 만들어야하고 확장성이 떨어짐 Transaction 실행 # connection의 beginTransaction과 commitTransaction으로 transaction 시작과 commit 수행 롤백 수행 : conn. ...

001 R2dbc Intro

December 5, 2023
2023-12-05
webflux, r2dbc

R2dbc 소개 # 왜 JDBC, JPA는 non-blocking을 지원할 수 없을까? # JDBC : 동기 blocking I/O 기반으로 설계 Socket에 대한 연결과 쿼리 실행 모두 동기 blocking으로 동작 JPA 또한 JDBC 기반 -> 비동기 non-blocking 지원 불가 그래서 결국, 비동기 non-blocing 기반의 API, 드라이버를 새로 만든다. R2dbc # Reactive Relational Database Connectivity 비동기 non-blocking 관계형 데이터베이스 드라이버 Reactive streams 스펙을 제공하며 Project reactor 기반으로 구현 R2dbc 지원 데이터베이스 # 공식지원 r2dbc-h2 r2dbc-mssql r2dbc-pool : Reactor pool로 커넥션 풀 제공 벤더 지원 oracle-r2dbc r2dbc-mariadb r2dbc-postgresql 커뮤니티 지원 r2dbc-mysql mirromutth 에서 2020년 5월부터 업데이트 X asyncer-io에서 RELEASE 지원 R2dbc MySQL 구조 # r2dbc-spi와 Reactor Netty 기반 Reactor Netty를 이용하여 r2dbc-spi 스펙을 구현 Reactor Netty client로 성능과 확장성 모두 제공 r2dbc-spi 스펙을 구현하여 여러 데이터베이스 시스템과 호환 R2dbc SPI # r2dbc Service Provider Interface SPI에서 제공하는 인터페이스를 구현해야한다. ...