我有三张桌子:
Users
Keys
UserKeys
用户键表具有来自用户和键表的主键,以建立用户和键之间的关系。
如何使用所有相关键获取用户?
如果存在其他表(例如,UserRoles)等,该怎么办?通常,如何获取用户和所有通过外键表相关的相关行?
我假设您正在使用jOOQ的代码生成器。编写连接就像在SQL中编写连接一样:
ctx.select() // Optionally, list columns here, explicitly
.from(USERS)
.join(USER_KEYS).on(USERS.ID.eq(USER_KEYS.USER_ID))
.join(KEYS).on(USER_KEYS.KEY_ID.eq(KEYS.ID))
.where(USERS.NAME.eq("something"))
.fetch();
如果存在其他表(例如UserRoles)等怎么办?通常,如何获取用户和所有关联的行,通过外键表关联?
我不确定这是否还是同一个问题。上述内容可能是关于如何进行连接的,这一部分似乎更具体地介绍了如何获取嵌套集合?
因为一旦连接多条路径,连接总是会产生笛卡尔积,这是不可取的。从jOOQ 3.14开始,如果您的数据库支持,您可以使用SQL/XML或SQL/JSON作为解决方法。从jOOQ 3.15开始,可以使用MULTISET。例如,JSON解决方案可能如下所示:
List<User> users =
ctx.select(jsonObject(
jsonEntry("id", USERS.ID),
jsonEntry("name", USERS.NAME),
jsonEntry("keys", field(
select(jsonArrayAgg(jsonObject(KEYS.NAME, KEYS.ID)))
.from(KEYS)
.join(USER_KEYS).on(KEYS.ID.eq(USER_KEYS.KEY_ID))
.where(USER_KEYS.USER_ID.eq(USER.ID))
)),
jsonEntry("roles", field(
select(jsonArrayAgg(jsonObject(ROLES.NAME, ROLES.ID)))
.from(ROLES)
.join(USER_ROLES).on(ROLES.ID.eq(USER_ROLES.ROLE_ID))
.where(USER_ROLES.USER_ID.eq(USER.ID))
))
))
.from(USERS)
.where(USERS.NAME.eq("something"))
.fetchInto(User.class);
假设用户类看起来像这样,并且类路径上有Gson或Jackson,可以从JSON映射到Java数据结构:
class Key {
long id;
String name;
}
class Role {
long id;
String name;
}
class User {
long id;
String name;
List<Key> keys;
List<Role> roles;
}
当然,您不必映射到Java数据结构并直接生成JSON结果,而无需进一步映射。有关更多详细信息,请参阅这篇博客文章,或者这篇文章解释了如何使用MULTISET。
请注意,JSON_ARRAYAGG()
将空集聚合到NULL
中,而不是空[]
中。如果有问题,请使用COALESCE()
MULTISET
解决方案如下所示:
List<User> users =
ctx.select(
USERS.ID,
USERS.NAME,
multiset(
select(KEYS.NAME, KEYS.ID)
.from(KEYS)
.join(USER_KEYS).on(KEYS.ID.eq(USER_KEYS.KEY_ID))
.where(USER_KEYS.USER_ID.eq(USER.ID))
).as("keys").convertFrom(r -> r.map(Records.mapping(Key::new))),
multiset(
select(ROLES.NAME, ROLES.ID)
.from(ROLES)
.join(USER_ROLES).on(ROLES.ID.eq(USER_ROLES.ROLE_ID))
.where(USER_ROLES.USER_ID.eq(USER.ID))
).as("roles").convertFrom(r -> r.map(Records.mapping(Role::new)))
)
.from(USERS)
.where(USERS.NAME.eq("something"))
.fetch(Records.mapping(User::new));
使用各种Records.mapping()
重载以及ad-hoc数据类型转换的上述方法假定存在不可变构造函数,例如如果您的类Java16条记录,您会得到:
record Key (int id, String name) {}
record Role (int id, String name) {}
record User (int id, String name, List<Key> keys, List<Role> roles) {}
是否有一种方法可以编程地列出所有在Jooq中作为外键的字段?它为外键生成了很多静态常量,但没有很好的方法以编程方式访问这些常量。 例如,我有一个表,其中有一个外键字段。在jOOQ中,假设我对的表对象有一个引用,那么似乎没有方法以编程方式获取对jOOQ字段对象的引用。因此,我现在唯一的解决方案是使用文字地图DataStructure在某个地方手动生成这些映射。似乎jooq可以为我做到这一点,我是不是
我有一个主键值,我想获取一个记录以进行更新,所以现在我写: JOOQ知道我的表的主键(例如,它会生成onKey()方法等)-因此我希望得到如下结果: 但这似乎不是一件事。有没有更简洁的方法使用JOOQ API来做我想要的事情?
我的数据库中有两个表: 如你所见,作者和书之间有一种关系:作者可以有很多书。在我的申请中,我想获取所有的作者,每个人都有他们的书籍收藏。现在我用代码实现了这个: 不幸的是,它需要对数据库进行许多查询。一个select用于获取作者,另外一个query用于为每个作者获取书籍。我试图连接表,但我不知道如何使用jooq正确解析结果。有什么想法吗?
我搞错了吗?或者JOOQ真的不能正确地处理特定表使用次数超过一次的查询吗??如果是,为什么这个不修好?? 最好的问候,期待您的意见。
我有一个问题..为什么要重复我在fetch方法中选择的内容。 所以我提供了CON\u CAL\u INSTANCE.DATE。min()在我的select子句中,为什么我必须在fetchOne(CON\u CAL\u INSTANCE.DATE.min())中重复它? 还是我做得不对?
我一直在使用模式。方法来获取模式中的表列表,但今天我发现该方法返回的是执行jOOQ代码生成时存在的表列表,而不是此时存在的表。 我的具体用例是随着时间的推移创建表(自动分区),我们的Java服务对它们执行一些操作。 在jOOQ中有没有办法从DB中获取当前的表列表? 我可以求助于查询信息模式。直接使用表,但我更愿意重用来自jOOQ的方法(如果可用的话)。