Avoiding casts when narrowing jooq selects

不问归期 提交于 2019-12-11 19:27:58

问题


Let's say I have a book database and I want to check whether the CLRS book has the correct authors.

Assuming 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));

    }

(Please ignore that it's very inefficient to join a whole table when we're just interested in one book, I'll make a separate question about that, if/when necessary.)

I now just want to select the AUTHOR.LASTNAME property instead of just everything.

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));

the cast to String in the authorNames generation is required because without it, I cannot compile because

Incompatible types. Required List but 'collect' was inferred to R: no instance(s) of type variable(s) exist so that Object conforms to String inference variable T has incompatible bounds: equality constraints: String lower bounds: Object

Is there a way to avoid this cast and still get the more narrow select?


回答1:


Without aliasing

I don't see why you rename your column. Just...

.select(AUTHOR.LASTNAME)

And then

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

With aliasing

If you must alias it, then it helps assigning the aliased column expression to a local variable:

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

// ...
.select(lastname)

... and then:

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

Alternatively, you can repeat the aliasing expression twice

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

... and then:

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


来源:https://stackoverflow.com/questions/55237064/avoiding-casts-when-narrowing-jooq-selects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!