Upgrade to Pro — share decks privately, control downloads, hide ads and more …

R2DBC = R2D2 + JDBC (enfin presque...)

R2DBC = R2D2 + JDBC (enfin presque...)

Présentation de R2DBC faite à Devoxx France en avril 2022

Bruno Bonnin

April 20, 2022
Tweet

More Decks by Bruno Bonnin

Other Decks in Programming

Transcript

  1. #DevoxxFR
    R2DBC = R2D2 + JDBC
    (enfin presque…)
    Bruno Bonnin @_bruno_b_
    1

    View Slide

  2. Rejoignez-nous: https://cbp.fr/nous-rejoindre
    Blog technique: https://cbp-group.github.io/
    Et pleins
    d’autres !

    View Slide

  3. Reactive Relational
    Database Connectivity

    View Slide

  4. Reactive API et base de données ?
    Driver Java v2
    X DevAPI
    (CompletableFuture)
    SqlClient
    ADBA
    JDBC Reactive Extension
    Reactive Driver

    View Slide

  5. Définit une interface
    standard de
    programmation réactive
    basée sur les Reactive
    Streams, destinée aux
    interactions avec les
    bases de données
    relationnelles. Reactive Streams
    R2DBC SPI
    R2DBC Driver X

    View Slide

  6. Publisher
    Subscriber
    1. subscribe
    3. request(n) / cancel
    2. onSubscribe (subscription)
    4. onNext(data 1)
    5. onComplete / onError
    Reactive Streams API
    Subscription
    4. onNext(data …)
    4. onNext(data n)

    View Slide

  7. Implémentation avec Project Reactor
    // Publisher de 0 à 1 élément
    public abstract class Mono
    implements CorePublisher {}
    Flux.just("Hello", "How", "Are", "You?")
    .doOnNext(System.out::println) // Data consumer
    .doOnError(exc -> System.err.println("Sniff… " + exc)) // Error consumer
    .doOnComplete(() -> System.out.println("Fini !!")) // Complete consumer
    .subscribe();
    // Publisher de 0 à n éléments
    public abstract class Flux
    implements CorePublisher {}

    View Slide

  8. ConnectionFactory connectionFactory =
    ConnectionFactories.get("r2dbc:h2:mem:///robot_db");
    R2DBC + Reactive Streams + Project Reactor = ❤
    Publisher extends Connection> connectionPublisher = connectionFactory.create();
    Mono.from(connectionPublisher)
    .flatMapMany(connection -> connection
    .createStatement("SELECT * FROM robot WHERE name = $1")
    .bind("$1", "R2-D2")
    .execute())
    .flatMap(result -> result.map((row, metadata) -> /* … */))
    .doOnNext(data -> …) // Traitement donnée
    .doOnError(exc -> …) // Traitement erreur
    .doOnComplete(() -> …) // Traitement fin
    .subscribe(); // Lancement du traitement

    View Slide

  9. Spring Data
    R2DBC

    View Slide

  10. spring:
    r2dbc:
    url: r2dbc:postgresql://localhost:15432/robot_db
    username: king_of_salsa
    password: un_truc_hyper_compliqué_noté_qqpart
    Tout commence par un
    peu de conf…

    View Slide

  11. DatabaseClient databaseClient =
    DatabaseClient.create(connectionFactory);
    Flux robots = databaseClient
    .sql("SELECT * FROM robot WHERE name = :name")
    .bind("name", name)
    .map(row -> …)
    .all();
    DatabaseClient

    View Slide

  12. Flux robots = r2dbcEntityTemplate
    .select(Robot.class)
    .from("robot")
    .matching(query(where("name").is(name)))
    .all();
    Flux robots = r2dbcEntityTemplate
    .select(
    query(where("name").is(name)),
    Robot.class);
    R2dbcEntityTemplate

    View Slide

  13. public interface RobotRepository
    extends ReactiveCrudRepository {
    Flux findByName(String name);
    @Query("select distinct movie from robot")
    Flux getMovies();
    }
    Reactive***Repository

    View Slide

  14. @Transactional
    public Mono create(Robot robot, Movie movie) {
    return robotRepository.save(robot)
    .then(movieRepository.save(movie))
    .then();
    }
    Et avec un zeste de transaction !
    public Mono create(Robot robot, Movie movie) {
    TransactionalOperator rxtx = TransactionalOperator.create(reactiveTxManager );
    return robotRepository.save(robot)
    .then(movieRepository.save(movie))
    .then()
    .as(rxtx::transactional);
    }

    View Slide

  15. Ecosystème - Drivers

    View Slide

  16. View Slide

  17. Écosystème - Clients

    View Slide

  18. R2DBC Proxy
    Librairie fournissant des
    callbacks permettant
    d’accéder à l’exécution
    des requêtes, pour:
    - logging,
    - métriques,
    - traçage distribué,
    - …
    R2DBC Proxy
    R2DBC Driver
    Application

    View Slide

  19. En résumé…
    Qu’a-t-on vu ?
    - Initiative plus qu’intéressante pour standardiser l’accès
    aux bases de données relationnelles en mode réactif
    - Il y a aussi des transactions, du batch, des entity
    callbacks, de l’observability, …
    - Support de la communauté (clients, drivers, …)
    - On peut faire du R2DBC sans aucun autre
    framework, mais ça va être un peu roots :)
    Mais il reste du boulot !
    - Des frameworks en cours de mises à jour (Liquibase, …)
    - Spring : pas de support des relations dans les entités :(

    View Slide

  20. #DevoxxFR
    Merci !
    @_bruno_b_
    Code des démos:
    https://github.com/bbonnin/intro-r2dbc
    20

    View Slide