So finally I coded this as below.
I'm new to this whole reactive paradigm. So the below code may not be the best way to do this. Eventually, I hope Spring Data R2DBC adds support for Page return type. The answer to the above question is in the search method implementation in the CustomMentorRepositoryImpl class.
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("mentors")
public class Mentor {
@Id
private Long id;
boolean hasId() {
return id != null;
}
@Version
@Column("version")
private Integer version;
@Column("name")
private String name;
@Column("age")
private Integer age;
}
Repository class
import com.sample.app.domain.Mentor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Repository
public interface MentorRepository extends
ReactiveCrudRepository<Mentor, String>, CustomMentorRepository {
}
// CustomRepository class
import com.sample.app.domain.Mentor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface CustomMentorRepository {
public Mono<Page<Mentor>> search(String name, Pageable page);
}
// CustomRepositoryImpl class
import lombok.AllArgsConstructor;
import com.sample.app.domain.Mentor;
import com.sample.app.repository.CustomMentorRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.core.DatabaseClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@AllArgsConstructor
public class CustomMentorRepositoryImpl implements CustomMentorRepository {
DatabaseClient databaseClient;
@Override
public Mono<Page<Mentor>> search(String name, Pageable page) {
Flux<Mentor> contents = databaseClient.execute("SELECT * FROM mentors where name like :name limit :limit offset :offset")
.bind("name", "%" + name + "%")
.bind("limit", page.getPageSize())
.bind("offset", page.getOffset())
.as(Mentor.class)
.fetch().all();
// Get the count
Mono<Long> count = databaseClient.execute("SELECT count(*) FROM mentors where name like :name")
.bind("name", "%" + name + "%")
.as(Long.class)
.fetch().first();
return contents.collectList().zipWith(count).flatMap(objects ->
Mono.just(new PageImpl<Mentor>(objects.getT1(), page, objects.getT2()))
);
}
}