缩小jooq选择范围时避免强制转换

时间:2019-03-19 09:02:48

标签: java sql select casting jooq

假设我有一个图书数据库,我想检查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:不存在类型变量的实例,因此Object符合String推断变量T具有不兼容的界限:相等约束:字符串下界:Object

是否有一种方法可以避免这种转换,并且还能获得更狭窄的选择?

1 个答案:

答案 0 :(得分:0)

没有别名

我不明白为什么要重命名列。只是...

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