跳到主要内容

普通属性

抓取标量字段

标量字段即数据库表中所有非关联字段。以抓取书籍名称为例:


BookTable book = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.createQuery(book)
.select(
book.fetch(
Fetchers.BOOK_FETCHER.name()
)
)
.execute();

备注

对Java而言,Annotation processor会为每一个实体接口自动生成一个Fetcher类,在这个例子中,就是BookFetcher

生成的SQL如下:

select 
tb_1_.ID,
/* highlight-next-line */
tb_1_.NAME
from BOOK as tb_1_
where tb_1_.EDITION = ?
备注

Java代码没有调用BookFetcher的id()方法,但是,我们看到SQL语句仍然查询了对象的id属性。

id属性被特殊对待,总是会被查询,并不受对象抓取器的控制。

事实上,自动生成BookFetcher类中也没有id()方法,因为不需要。

打印的结果如下(原输出是紧凑的,为了方便阅读,这里进行了格式化):

[
{
"id":3,
"name":"Learning GraphQL"
},
...省略其他对象...
]

抓取多个字段

BookTable book = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.createQuery(book)
.select(
book.fetch(
Fetchers.BOOK_FETCHER
.name()
.edition()
)
)
.execute();
信息

对象抓取器是不可变对象,每一次链式调用都会返回一个新的对象抓取器。

即,上述Java代码中

  • Fetchers.BOOK_FETCHER
  • Fetchers.BOOK_FETCHER.name()
  • Fetchers.BOOK_FETCHER.name().edition()

是三个不同的对象抓取器,每一个都是不可变的。

对象抓取器是不可变对象,所以你可以借助静态变量随意共享对象抓取器。

生成的SQL如下:

select 
tb_1_.ID,
/* highlight-next-line */
tb_1_.NAME,
/* highlight-next-line */
tb_1_.EDITION
from BOOK as tb_1_
where tb_1_.EDITION = ?

打印的结果如下(原输出是紧凑的,为了方便阅读,这里进行了格式化):

[
{
"id":3,
"name":"Learning GraphQL",
"edition":1
},
...省略其他对象...
]

抓取所有标量字段

在一些场景下,抓取所有非关联字段是非常常用的操作,因此提供了allScalarFields()用于加载所有非关联字段。

BookTable book = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.createQuery(book)
.select(
book.fetch(
Fetchers.BOOK_FETCHER.allScalarFields()
)
)
.execute();

生成的SQL如下:

select 
tb_1_.ID,
// highlight-start
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE
// highlight-end
from BOOK as tb_1_
where tb_1_.EDITION = ?

打印的结果如下(原输出是紧凑的,为了方便阅读,这里进行了格式化):

{
"id":3,
"name":"Learning GraphQL",
"edition":3,
"price":51.00
}
// 省略其他对象
信息

allScalarFields()只会加载非关联字段,示例中可以看到查询了id, name, edition, price,但是并没有查询storeauthors这两个关联属性。

抓取关联属性将在下一篇文档中介绍。

负属性(排除不需要的属性)

前面讲过的属性都是正属性,不断新增要查询的字段。但一些场景下,我们只需要排除一些指定字段,其他的字段则都要查询。

这时候就可以用负属性去排除不需要的字段。

BookTable book = Tables.BOOK_TABLE;

List<Book> books = sqlClient
.createQuery(book)
.select(
book.fetch(
Fetchers.BOOK_FETCHER
.allScalarFields()
.edition(false)
)
)
.execute();

edition(false)使用参数false,这就是负属性。

  • allScalarFields()的属性是id + name + edition + price

  • edition(false)表示-edition

所以,最终并在一起,最终被抓取的属性是id + name + price

信息
  • 对于正属性而言,edition()edition(true)等价
  • 当大部分属性需要抓取,只有少部分属性不需要抓取时,allScalarFields和负属性结合使用会非常有用

生成的SQL如下:

select 
tb_1_.ID,
tb_1_.NAME,
tb_1_.PRICE
from BOOK as tb_1_
where tb_1_.EDITION = ?

打印的结果如下(原输出是紧凑的,为了方便阅读,这里进行了格式化):

[
{
"id":3,
"name":"Learning GraphQL",
"price":51.00
// 这里没有`edition`
},
...省略其他对象...
]