6

The org.springframework.r2dbc DatabaseClient class has moved to

import org.springframework.r2dbc.core.DatabaseClient;

from

import org.springframework.data.r2dbc.core.DatabaseClient;

The Spring data documentation https://spring.io/projects/spring-data-r2dbc refers to a simple 'as' method to convert to an object

   databaseClient
        .sql("select * from reading")
        .as(CrepsReading::class.java)
        .fetch()
        .all()
        .asFlow()

It doesn't wok. Neither does map(class). Only mapping class seems to work.

     val all: Flux<CrepsReading> = databaseClient
            .sql("SELECT id, name FROM person")
            .map(CrepsReading::class)
            .fetch().all()

How do you map an object with spring-data-r2dbc (1.2.0) simply? Is there documentation that describes the use of the DatabaseClient that is part of spring-data-r2dbc?

Interlated
  • 5,108
  • 6
  • 48
  • 79
  • Have you looked into using Spring Data repositories with R2DBC? I am referring to the getting started documentation here: https://docs.spring.io/spring-data/r2dbc/docs/1.2.0-M2/reference/html/#r2dbc.getting-started – Michael Paesold Nov 12 '20 at 06:26
  • I'm trying to piece the locations together. That documentation as the 'as' syntax which doesn't work for me. I've had to go to Spring Boot '2.4.0-RC1' to get Spring 5.3 which might explain some of my confusion. – Interlated Nov 12 '20 at 20:26
  • If it is indeed Kotlin, I wonder how you call the `as` function, as `as` is a keyword in Kotlin. You have to put the call in backquotes, which I cannot demonstrate here due to my lack of Markdown knowledge. (How do I escape the backticks?) – Michael Piefel Jan 02 '21 at 18:07
  • `.\`as\`(CrepsReading::class.java)` – Michael Piefel Jan 02 '21 at 18:21
  • See @Hantsy comment below regarding the ORM now being split into R2dbcEntityTemplate – Interlated Jan 02 '21 at 19:23

1 Answers1

6

In Spring 5.3/Spring Data R2dbc, the DatabaseClient is refactored and moved to the core of Spring framework.

Check my example to view how to handle the resulting map.

    public static final BiFunction<Row, RowMetadata, Post> MAPPING_FUNCTION = (row, rowMetaData) -> Post.builder()
            .id(row.get("id", UUID.class))
            .title(row.get("title", String.class))
            .content(row.get("content", String.class))
            .status(row.get("status", Post.Status.class))
            .metadata(row.get("metadata", Json.class))
            .createdAt(row.get("created_at", LocalDateTime.class))
            .build();

    private final DatabaseClient databaseClient;

    public Flux<Post> findByTitleContains(String name) {
        return this.databaseClient
                .sql("SELECT * FROM posts WHERE title LIKE :title")
                .bind("title", "%" + name + "%")
                .map(MAPPING_FUNCTION)
                .all();
    }
Hantsy
  • 8,006
  • 7
  • 64
  • 109
  • Yes. I've looked at your example. It is great, thanks. Has .map(MAPPING_FUNCTION) which is a departure from 'as'. I don't know whether 'as' magic is a good thing but avoiding more mapping is attractive. – Interlated Nov 23 '20 at 00:38
  • 1
    For entity mapping, use `R2dbcEntityTemplate` instead, check [my example](https://github.com/hantsy/spring-r2dbc-sample/blob/master/data-r2dbc-entitytemplate/src/main/java/com/example/demo/PostRepository.java). – Hantsy Nov 23 '20 at 03:04
  • 1
    The functionality of the original `DatabaseClient` is split into the new `DatabaseClient` and `R2dbcEntityTemplate`. – Hantsy Nov 23 '20 at 03:10
  • @Hantsy can you use sql string for the query if using `R2dbcEntityTemplate`? didn't see it in your example. e.g. `.sql("select * from reading")` – billydh Apr 30 '21 at 05:43
  • @billydh Stated in the above comments. – Hantsy Apr 30 '21 at 06:11