Node.js中mysql2如何将关联表结果封装为对象数组
解决mysql2查询关联表后自动嵌套posts数组的问题
方法1:利用MySQL的JSON聚合函数(推荐)
直接在SQL层将posts聚合为JSON数组,mysql2会自动将JSON字段解析为JavaScript数组,无需额外处理。
适用于MySQL 5.7及以上版本(支持JSON函数):
SELECT U.id, U.name, COALESCE( JSON_ARRAYAGG( JSON_OBJECT( 'id', P.id, 'user_id', P.user_id -- 可添加posts表其他需要的字段 ) ), JSON_ARRAY() ) AS posts FROM users U LEFT JOIN posts P ON U.id = P.user_id GROUP BY U.id, U.name;
查询后mysql2直接返回目标结构:
[ { id: 1, name: 'John', posts: [ { id: 1, user_id: 1 }, { id: 2, user_id: 1 }, { id: 3, user_id: 1 } ] } ]
用
COALESCE是为了处理用户无对应posts的情况,确保posts字段始终是数组而非NULL。
方法2:mysql2的nestTables配置(配合简易分组)
如果不想修改SQL,可以开启mysql2的nestTables选项,将不同表的字段嵌套到对应对象中,再用简单逻辑分组:
const [rows] = await this.connection.query( 'SELECT * FROM users U LEFT JOIN posts P on U.id = P.user_id', { nestTables: true } // 开启表字段嵌套,避免字段名冲突 ); const usersMap = new Map(); for (const row of rows) { const userId = row.U.id; if (!usersMap.has(userId)) { usersMap.set(userId, { ...row.U, posts: [] }); } // 仅当存在有效post时添加 if (row.P.id) { usersMap.get(userId).posts.push(row.P); } } const result = Array.from(usersMap.values());
关于mysql2底层自动处理的说明
mysql2作为轻量MySQL客户端,核心是准确返回数据库原生查询结果,关联结果的分组属于业务逻辑层面的转换,默认不会内置这类功能。SQL聚合的方式更高效——聚合逻辑由数据库处理,既减少客户端数据传输量,也降低前端处理成本。
内容的提问来源于stack exchange,提问作者Dmytro Bilozor
相关产品推荐
相关产品推荐

