我正在尝试从另一个数据库表将数据加载到网格中。
我的网格是从User
实体创建的
private Grid<User> grid = new Grid<>(User.class, false);
User
有几个类似的列
private Long userId;
private String username;
private String email;
.
.
.
User
也包含来自第二个表(实体(的记录标识符:
private Long organizationId;
所以我在网格中添加了列:
grid.addColumn(User::getUserId).setAutoWidth(true).setHeader("id");
grid.addColumn(User::getUsername).setAutoWidth(true).setHeader("login");
我创造了我的";拥有";使用来自另一个表(实体(的数据的列:
grid.addColumn(user -> organizationService.findOrganizationNameByOrganizationId(user.getOrganizationId()).setAutoWidth(true).setHeader("organization name");
但问题是,加载非常慢,因为User
表有大约500 000 rows
,并且它为每一行向数据库发送查询。。。
是否可以通过user entity
中定义的organization id
批量加载organization name
,例如?
首先,如果我没有必要。如果解决方案像连接数据一样简单在数据库中,创建一个视图。。。那就这么做吧。
然而,有时,这必须有效地完成,因为数据致富并非来自同一个来源。
我认为最好的地方是作为懒惰加载的一部分数据一旦您持有当前加载页面的流,您可以通过流map
并丰富数据,或者进行批处理加载等等。选择最有效的。
如果你必须经常这样做,一定要在里面提供有用的工具您的存储库;为了只为一个网格快速添加内容,您可以以及劫持DataProvider或其继任者。
以下示例(注意XXX
(:
@Route("")
class GridView extends Div {
GridView() {
add(new Grid<User>(User).tap {
setItems({ q ->
// XXX: this materializes the stream first to get all
// unique organizationId:s, batch-load the
// Organization, and finally transform the User
def users = FakeUserRepo.page(q.offset, q.limit).toList()
def orgaMap = FakeOrganizationRepo.batchLoad(users*.organizationId.toSet())
users.stream().map {
it.organizationName = orgaMap[it.organizationId].name; it
}
}, { q ->
FakeUserRepo.count()
})
})
}
}
@TupleConstructor
class Organization {
Integer id
String name
}
class FakeOrganizationRepo {
public static final Map<Integer, Organization> ORGANIZATIONS = (0..<5).collectEntries { [it, new Organization(it, "Organization $it")] }
static Map<Integer, Organization> batchLoad(Set<Integer> ids) {
ORGANIZATIONS.subMap(ids)
}
}
@TupleConstructor
class User {
Integer id
String name
Integer organizationId
String organizationName
}
class FakeUserRepo {
public static final Collection<User> USERS = (1..500_000).collect {
new User(it, "User $it", it % FakeOrganizationRepo.ORGANIZATIONS.size())
}
static int count() {
USERS.size()
}
static Stream<User> page(int offset, int limit) {
USERS.stream().skip(offset).limit(limit)
}
}