Spring Webflux - R2dbc: Как запустить дочерний запрос и обновить значение при итерации набора результатов

Я новичок в реактивных репозиториях и webflux. Я получаю список данных из БД, повторяя его с помощью map() для создания объекта класса DTO, в этом процессе мне нужно запустить другой запрос, чтобы получить значение счетчика и обновить тот же объект DTO. Когда я пытаюсь сделать следующее, счетчик устанавливается равным нулю

@Repository
public class CandidateGroupCustomRepo {
  public Flux<CandidateGroupListDTO> getList(BigInteger userId){
        final String sql = "SELECT gp.CANDIDATE_GROUP_ID,gp.NAME  ,gp.GROUP_TYPE   \n" +
                "                             ,gp.CREATED_DATE  ,cd.DESCRIPTION STATUS ,COUNT(con.CANDIDATE_GROUP_ID)\n" +
                "                             FROM  ........" +
                "                             WHERE gp.CREATED_BY_USER_ID = :userId  GROUP BY gp.CANDIDATE_GROUP_ID,gp.NAME  ,gp.GROUP_TYPE   \n" +
                "                             ,gp.CREATED_DATE  ,cd.DESCRIPTION";
        return dbClient.execute(sql)
                .bind("userId", userId)
                .map(row ->{
                            CandidateGroupListDTO info = new CandidateGroupListDTO();
                            info.setGroupId(row.get(0, BigInteger.class));
                            info.setGroupName(row.get(1, String.class)) ;
                            info.setGroupType(row.get(2, String.class));
                            info.setCreatedDate( row.get(3, LocalDateTime.class));
                            info.setStatus(row.get(4, String.class));

                            if(info.getGroupType().equalsIgnoreCase("static")){
                                info.setContactsCount(row.get(5, BigInteger.class));
                            }else{
                getGroupContactCount(info.getGroupId()).subscribe(count ->{
                    System.out.println(">>>>>"+count);
                    info.setContactsCount(count);
                
                        });
                            }
                            return info;
                            }
                        )
                .all() ;
    }
    
    Mono<BigInteger> getGroupContactCount(BigInteger groupId){
            final String sql = "SELECT 3 WHERE :groupId IS NOT NULL;";
            return dbClient.execute(sql)
                    .bind("groupId", groupId)
                    .map(row -> {
                        System.out.println(row.get(0, BigInteger.class));
                        return row.get(0, BigInteger.class);
                    }  ).one();
    }
    
}

Когда я вызываю getGroupContactCount, я пытаюсь извлечь счетчик из Mono<BigInteger> и установить его в моем DTO .... sys out правильно распечатывает значение счетчика, но все же в ответ я получаю ноль для счетчика.


person Siva Sakthi    schedule 16.04.2021    source источник


Ответы (1)


Вы звоните subscribe посередине, что, в свою очередь, по сути блокирует. Тот, кто подписывается, обычно является конечным потребителем, которым, как я предполагаю, не является ваше весеннее приложение, скорее всего, конечным потребителем является веб-страница, которая инициировала вызов. Ваш сервер - производитель.

вызовите базу данных, flatMap и вернитесь.

return dbClient.execute(sql)
    .bind("userId", userId)
    .flatMap(row ->{
        CandidateGroupListDTO info = new CandidateGroupListDTO();
        info.setGroupId(row.get(0, BigInteger.class));
        info.setGroupName(row.get(1, String.class)) ;
        info.setGroupType(row.get(2, String.class));
        info.setCreatedDate( row.get(3, LocalDateTime.class));
        info.setStatus(row.get(4, String.class));

        if(info.getGroupType().equalsIgnoreCase("static")){
            return Mono.just(info.setContactsCount(row.get(5, BigInteger.class)));
        } else {
            return getGroupContactCount(info.getGroupId()).flatMap(count -> {
                info.setContactsCount(count);
                return Mono.just(info)
            });
        }
    }).all();

Используйте map, если порядок имеет значение, в противном случае попробуйте использовать flatMap для асинхронной работы.

person Toerktumlare    schedule 16.04.2021