jooq多表查询_三、jOOQ 系列教程 - 查询结果处理

本文介绍了jOOQ如何处理查询结果,包括Fetch系列API的使用,如fetch、fetchOne等,以及如何将结果转换为POJO、Map等格式。重点讨论了在多表查询时字段相同的情况下的处理方法,并提供了示例代码。
摘要由CSDN通过智能技术生成

POJO是一个简单的Java对象,主要是包含一些属性和 getter/setter 方法,在业务中常用到的是用于传输数据以及作为参数传递。 在Web应用的场景中,也通常用来和前端做数据交互

jOOQ的代码生成器能够帮我们根据表结构生成对应的POJO,能很大程度上减少我们自己创建POJO的工作量,当然,此功能也是大部分ORM框架的必备功能。本章主要讲解各种方式将数据结果转换为我们想要的格式

Fetch 系列 API

查询操作通常以fetch API 作为结束API,例如常用的有,所有的读取类方法都差不多,掌握一个就能很快的举一反三读取多条fetch 读取集合

fetchSet 读取并返回一个Set集合,常用于去重

fetchArray 读取并返回一个数组

读取单条fetchOne 读取单条记录,如果记录超过一条会报错

fetchAny 读取单条记录,如果有多条,会取第一条数据

fetchSingle 读取单条记录,如果记录为空或者记录超过一条会报错

读取并返回MapfetchMap 读取并返回一个Map

fetchGroups 读取并返回一个分组Map

fetch

作为一个常用的读取多条记录的API,其他几个读取多条的方法和这个方法类似,只是返回值不同

fetchSet, fetchArray 方法和 fetch 方法一样,都是返回多条数据,只是返回的格式不同,fetch通常返回List或者jOOQ的Result对象

接下来介绍一下几个方法重载的返回值fetch() 无参调用此方法,返回的是一个Result结果集对象

Result records = dslContext.select().from(S1_USER).fetch();fetch(RecordMapper mapper) RecordMapper接口的提供map方法,用于来返回数据。map 方法传入一个 Record 对象。可以使用lambda表达式将 Record 对象转换成一个指定类型的POJO

List userPojoList = dslContext.select()

.from(S1_USER)

.where(S1_USER.ID.eq(1))

.fetch(r -> r.into(S1UserPojo.class));

多表查询,字段相同时,直接用into方法将结果集转换为POJO时,相同字段名称的方法会以最后一个字段值为准。这时候,我们可以现将结果集通过 `into(Table table)` 方法将结果集转换为指定表的`Record`对象,然后再`into`进指定的POJO类中

// 多表关联查询,查询s2_user_message.id = 2的数据,直接into的结果getId()却是1// 这是因为同时关联查询了s1_user表,该表的id字段值为1List userMessage = dslContext.select().from(S2_USER_MESSAGE)

.leftJoin(S1_USER).on(S1_USER.ID.eq(S2_USER_MESSAGE.USER_ID))

.where(S2_USER_MESSAGE.ID.eq(2))

.fetch(r -> r.into(S2UserMessage.class));

// userMessage.getId() == 1

// 将结果集into进指定的表描述中,然后在into至指定的POJO类List userMessage2 = dslContext.select().from(S2_USER_MESSAGE)

.leftJoin(S1_USER).on(S1_USER.ID.eq(S2_USER_MESSAGE.USER_ID))

.where(S2_USER_MESSAGE.ID.eq(2))

.fetch(r -> {

S2UserMessage fetchUserMessage = r.into(S2_USER_MESSAGE).into(S2UserMessage.class);

fetchUserMessage.setUsername(r.get(S1_USER.USERNAME));

return fetchUserMessage;

});

// userMessage.getId() == 2fetch(Field> field) Field是一个接口,代码生成器生成的表字段常量例如 S1_USER.ID, 都实现了 Field 接口,这个重载可以直接取出指定表字段,会自动根据传入的字段推测其类型

List id = dslContext.select().from(S1_USER).where(S1_USER.ID.eq(1))

.fetch(S1_USER.ID);fetch(String fieldName, Class> type) 可以直接通过字段名称字符串获取指定字段值,可以通过第二个参数指定返回值,如果不指定,返回Object

List idList = dslContext.select().from(S1_USER).where(S1_USER.ID.eq(1))

.fetch("id", Integer.class);fetch(int fieldIndex, Class> type) 可以通过查询字段下标顺序进行查询指定字段,可以通过第二个参数指定返回值,如果不指定,返回Object

List idList = dslContext.select(S1_USER.ID, S1_USER.USERNAME)

.from(S1_USER).where(S1_USER.ID.eq(1)).fetch(0, Integer.class);

fetch*

fetchSet, fetchArray, fetchAny, fetchOne, fetchSingle 这几个方法的和 fetch 方法的用法一致,只是返回值不同,这里不做详解

fetchAny, fetchOne, fetchSingle 方法返回单条数据,但是对于 数据为空、SQL结果为多条数据 的情况下,处理方式各不相同org.jooq.exception.TooManyRowsException 多条数据时抛出异常

org.jooq.exception.NoDataFoundException 无数据时抛出异常

fetchMap

此方法可以将结果集处理为一个Map格式,此方法有很多重载,这里介绍几个常用的,注意,此方法作为key的字段必须确定是在当前结果集中是唯一的,如果出现重复key,此方法会抛出异常fetchMap(Field field, Class type) 以表字段值为key,返回一个 K:V 的Map对象

Map idUserPojoMap = dslContext.select().from(S1_USER)

.fetchMap(S1_USER.ID, S1UserPojo.class);fetchMap(Feild field, Field field) 以表字段值为key,返回一个 K:V 的Map对象

Map idUserNameMap = dslContext.select().from(S1_USER)

.fetchMap(S1_USER.ID, S1_USER.USERNAME);

fetchGroups

此方法可以将结果集处理为一个Map格式,和fetchMap类似,只不过这里的值为一个指定类型的集合,通常在处理一对多数据时会用到fetchGroups(Field field, Class type) 以表字段值为Key,返回一个K:List 的Map对象

Map> userIdUserMessageMap = dslContext.select().from(S2_USER_MESSAGE)

.fetchGroups(S2_USER_MESSAGE.USER_ID, S2UserMessage.class);fetchGroups(Field keyField, Field valueField)

以表字段值为Key,返回一个K:List 的Map对象

Map> userIdUserMessageIdMap = dslContext.select().from(S2_USER_MESSAGE)

.fetchGroups(S2_USER_MESSAGE.USER_ID, S2_USER_MESSAGE.ID);

内容总结

文章主要讲解的是各种类型的读取API,掌握好这些API对于jOOQ的使用很有帮助

本章中出现的一下几个接口可能是在编码过程中经常遇到的Field 接口 由代码生成器生成的所有表字段常量,都是此接口的实现类,包含了字段一些基本信息,例如字段名称,字段数据类型等,所有读取类方法都有基于此字段参数的重载

RecordMapper super R, E> mapper 接口 该接口很简单,主要是提供一个 map 方法给大家去实现。此接口只有一个方法,可以通过lambda表达式快速实现该接口。所有读取类方法都有基于此接口参数的重载

public interface RecordMapper {

E map(R record);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值