Избегание бросков при сужении jooq - PullRequest
0 голосов
/ 19 марта 2019

Допустим, у меня есть база данных книг, и я хочу проверить, есть ли в книге CLRS правильные авторы.

Предполагая private static final String CLRS_title = "Introduction to Algorithms";

    @Test
    public void CLRS_is_written_by_CLRS(){
        //given        
        SelectConditionStep<Record> query = create
                .select()
                    .from(
                            (
                                    BOOK.leftOuterJoin(BOOK_AUTHOR).on(BOOK.ID.eq(BOOK_AUTHOR.BOOKID))
                            ).leftOuterJoin(AUTHOR).on(AUTHOR.ID.eq(BOOK_AUTHOR.AUTHORID))
                    )
                    .where(BOOK.TITLE.eq(CLRS_title))
                ;

        //when
        Result<Record> result = query.fetch();
        List<String> authorNames = result.stream().map(r-> r.getValue(AUTHOR.LASTNAME)).collect(Collectors.toList());

        //then
        assertThat(authorNames.size(),is(4));
        assertThat(authorNames.containsAll(Arrays.asList("Cormen","Leiserson","Rivest","Stein")), is(true));

    }

(Пожалуйста, игнорируйте, что очень неэффективно объединять целую таблицу, когда мы просто заинтересованы в одной книге, я задам отдельный вопрос об этом, если / когда это будет необходимо.)

Теперь я просто хочу выбрать свойство AUTHOR.LASTNAME вместо всего.

SelectConditionStep<Record1<String>> query = create
        .select(AUTHOR.LASTNAME.as("AuthorName"))
            .from(
                    (
                            BOOK.leftOuterJoin(BOOK_AUTHOR).on(BOOK.ID.eq(BOOK_AUTHOR.BOOKID))
                    ).leftOuterJoin(AUTHOR).on(AUTHOR.ID.eq(BOOK_AUTHOR.AUTHORID))
            )
            .where(BOOK.TITLE.eq(CLRS_title))
        ;

//when
Result<Record1<String>> result = query.fetch();
List<String> authorNames = result.stream().map(r-> (String)r.getValue("AuthorName")).collect(Collectors.toList());

//then
assertThat(authorNames.size(),is(4));
assertThat(authorNames.containsAll(Arrays.asList("Cormen","Leiserson","Rivest","Stein")), is(true));

приведение к String в поколении authorNames требуется, потому что без него я не могу скомпилировать, потому что

Несовместимые типы. Обязательный список, но 'collect' был выведен в R: не существует экземпляра (ов) переменной (ей) типа, так что объект соответствует строковой переменной вывода T имеет несовместимые границы: ограничения равенства: нижние границы строки: объект

Есть ли способ избежать этого броска и все же получить более узкий выбор?

1 Ответ

0 голосов
/ 20 марта 2019

Без псевдонимов

Я не понимаю, почему вы переименовали свою колонку.Просто ...

.select(AUTHOR.LASTNAME)

А затем

List<String> authorNames = result.getValues(AUTHOR.LASTNAME);

с псевдонимом

Если вы должны назвать его псевдонимом, то это помогает назначить псевдонимВыражение столбца для локальной переменной:

Field<String> lastname = AUTHOR.LASTNAME.as("lastname");

// ...
.select(lastname)

... и затем:

List<String> authorNames = result.getValues(lastname);

В качестве альтернативы, вы можете повторить выражение псевдонима дважды

.select(AUTHOR.LASTNAME.as("lastname"))

... а затем:

List<String> authorNames = result.getValues(AUTHOR.LASTNAME.as("lastname"));
...