JOOQ技术问询:如何查询部分表全字段及指定表特定字段
JOOQ查询优化:获取部分表全字段+指定表特定字段
问题背景
现有以下JOOQ查询代码(已修正原代码拼写错误CUSTOMRS为CUSTOMERS,补全语法缺失):
dsl.select( CUSTOMERS.ID, CUSTOMERS.NAME, CUSTOMERS.ADDRESS, ORDERS.ID, ORDERS.PRICE, ORDERS.PRODUCT_ID, PRODUCTS.NAME ) .from(CUSTOMERS) .join(ORDERS).on(ORDERS.ID.eq(CUSTOMERS.ORDER_ID)) .join(PRODUCTS).on(ORDERS.PRODUCT_ID.eq(PRODUCTS.ID)) .fetch();
需求是:无需逐个列出列名编写查询,同时实现获取部分表的全部字段,仅获取指定表的特定字段。既想降低新增表列时遗漏添加到查询的概率,又不想使用.asterisk()/SELECT *(避免生产环境常见问题)。是否存在类似以下假想示例的实现方式?
dsl.select( CUSTOMERS.columns(), ORDERS.columns(), PRODUCTS.NAME ) .from(CUSTOMERS) .join(ORDERS).on(ORDERS.ID.eq(CUSTOMERS.ORDER_ID)) .join(PRODUCTS).on(ORDERS.PRODUCT_ID.eq(PRODUCTS.ID)) .fetch();
解决方案
完全可以实现,JOOQ提供了Table.fields()方法来获取表的全部字段,结合指定字段即可满足需求:
正确代码示例
最简洁的写法(利用Java可变参数的数组展开特性):
dsl.select( CUSTOMERS.fields(), ORDERS.fields(), PRODUCTS.NAME ) .from(CUSTOMERS) .join(ORDERS).on(ORDERS.ID.eq(CUSTOMERS.ORDER_ID)) .join(PRODUCTS).on(ORDERS.PRODUCT_ID.eq(PRODUCTS.ID)) .fetch();
若编译器提示参数类型不匹配,可显式转换数组类型:
dsl.select( (Field<?>[]) CUSTOMERS.fields(), (Field<?>[]) ORDERS.fields(), PRODUCTS.NAME ) .from(CUSTOMERS) .join(ORDERS).on(ORDERS.ID.eq(CUSTOMERS.ORDER_ID)) .join(PRODUCTS).on(ORDERS.PRODUCT_ID.eq(PRODUCTS.ID)) .fetch();
方案优势
- 避免手动逐个列名:
fields()直接获取表的全部字段,新增列后只需重新生成JOOQ代码,字段会自动纳入查询,不会遗漏。 - 规避
SELECT *风险:fields()是代码生成阶段确定的字段集合,而非运行时解析的通配符,不会出现返回多余字段、字段顺序不确定、schema变更兼容性问题等生产环境常见问题。
内容的提问来源于stack exchange,提问作者Offbeat Upbeat
相关产品推荐
相关产品推荐

