跳到主要内容

1. 基本查询

Jimmer中有两个概念

  • 查询多列
  • 查询一个对象列,并指定被查询对象的多个属性

它们是完全不同的概念

查询多列

BookTable table = BookTable.$;

List<Tuple3<Long, String, Integer>> tuples = sqlClient
.createQuery(table)
.where(table.name().eq("GraphQL in Action"))
.orderBy(table.edition().desc())
.select(
table.id(),
table.name(),
table.edition()
)
.execute();

在Jimmer中,除了只返回一列的查询外,其他都是多列查询。这个例子查询了三列,故返回类型为Tuple3<T1, T2, T3>

等到如下数据

[
{
"_1" : 12,
"_2" : "GraphQL in Action",
"_3" : 3
}, {
"_1" : 11,
"_2" : "GraphQL in Action",
"_3" : 2
}, {
"_1" : 10,
"_2" : "GraphQL in Action",
"_3" : 1
}
]

指定被查询对象的多个属性

BookTable table = BookTable.$;

List<Book> books = sqlClient
.createQuery(table)
.where(table.name().eq("GraphQL in Action"))
.orderBy(table.edition().desc())
.select(
table.fetch(
BookTableFetcher.$
// `id()`是隐含的,总是被查询
.name()
.edition()
)
)
.execute();

等到如下数据

[
{
"id" : 12,
"name" : "GraphQL in Action",
"edition" : 3
},
{
"id" : 11,
"name" : "GraphQL in Action",
"edition" : 2
},
{
"id" : 10,
"name" : "GraphQL in Action",
"edition" : 1
}
]

不难看出,虽然这个查询只有一列,但是我们可以精确地控制这个对象的格式。

这个例子并没有查询出Book对象的所有属性 (price和多对一关联store未被查询),由于Jimmer实体对象Book执行动态特性,对象被查询属性的多或少不会影响返回类型,一律为Book类型。

提示

Jimmer实体对象具备动态性,可以用统一的类型表达任意格式的对象。

因此,Jimmer下不需要使用多列查询来控制返回格式,我们更应该使用单列查询返回一列对象,并灵活控制对象格式。

这会导致Jimmer很少使用基于元组的多列查询,更加面向对象。

综合应用二者

BookTable table = BookTable.$;

List<Tuple2<Book, Integer>> tuples = sqlClient
.createQuery(table)
.where(table.name().eq("GraphQL in Action"))
.orderBy(table.edition().desc())
.select(
table.fetch(
BookFetcher.$
.allScalarFields()
),
Expression.numeric().sql(
Integer.class,
"row_number() over(partition by %e order by %e desc)",
new Expression<?>[] { table.storeId(), table.price() }
)
)
.execute();

得到的结果为

[
{
"_1":{
"id":12,
"name":"GraphQL in Action",
"edition":3,
"price":80
},
"_2":3
},
{
"_1":{
"id":11,
"name":"GraphQL in Action",
"edition":2,
"price":81
},
"_2":2
},
{
"_1":{
"id":10,
"name":"GraphQL in Action",
"edition":1,
"price":82
},
"_2":1
}
]

这个例子查询类两列

  • 第一列为对象类型,对象格式为allScalarFields(包含所有非关联属性)

  • 第二列是一个Native SQL表达式,调用底层数据库的分析函数 (%e表示用为Native SQL代码植入DSL表达式)

很明显这是二者的综合运用。