11

从单个MySQL 选择查询中检索来自两个连接表的所有信息的最佳和最优雅的方法是什么,但是以分层的方式?

我有这两张桌子:

-----------------         ------------------
| Table COMPANY |         | Table EMPLOYEE |
-----------------         ------------------
| id            |         | id             |
| companyName   |         | companyId      |
-----------------         | employeeName   |
                          ------------------

(for each company, many employees)

我想输出以下分层 JSON 片段:

[
    {"id": 1,
     "companyName": "Company A",
     "employees": [
         {"id": 1, "employeeName": "Employee 1"},
         {"id": 2, "employeeName": "Employee 2"}
    ]},
    {"id": 2,
     "companyName": "Company B",
     "employees": [
         {"id": 3, "employeeName": "Employee 3"},
         {"id": 4, "employeeName": "Employee 4"}
    ]}
]

“解决方案”1:

对连接的表进行全选,并在创建 json 片段后编写一些代码:

select * from company, employee where employee.companyId = company.id;

问题:我留下了很多丑陋的 foreach 类型代码来创建 json 片段

“解决方案”2:

按公司所有员工在 json 字符串中分组:

select company.id, company.name,
   concat('[',
      group_concat('{"id": ', employee.id, ',
         "employeeName": "', employee.employeeName,'"}'), ']') as employees
from company, employee where company.id = employee.companyId
group by company.id

这里,“employees”已经是一个json片段,我只需要jsonify company.id和name即可。但是在 mysql 中构建 json 片段似乎是非常糟糕的做法。

任何见解或其他解决方案?

非常感谢

4

2 回答 2

2

我可能会使用像您的解决方案 1 这样的查询,只需添加“按 company.id 排序”,然后在表中循环一次,为每一行建立一个数据结构,如果公司与前一个相同一,将员工数据推送到公司,否则,定义新公司并开始使用它来推送员工数据。

像 Carlos Quijano 一样,我在这里看不到任何 foreach 混乱。(但有排序使它更容易处理)

于 2012-10-30T11:55:19.440 回答
1

因为您需要运行单个 MySQL 查询并且不想弄乱针对每种类型的丑陋代码,所以您可能应该返回一个无层次的 JSON 结果,您可以通过序列化查询结果来为您的代码添加一些优雅到带有 DbUtils 查询的集合。

QueryRunner 运行 = new QueryRunner(dataSource);

// Use the BeanListHandler implementation to convert all
// ResultSet rows into a List of Employees JavaBeans.
ResultSetHandler<List<Employee>> handler = new BeanListHandler<Employee>(Employee.class);

// Execute the SQL statement and return the results in a List of
// Person objects generated by the BeanListHandler.
List<Employee> employees = run.query("SELECT * FROM EMPLOYEE ORDER BY COMPANY_ID", handler);

但是,如果您需要生成分层 JSON 结果,我同意下面的 MortenSickel 回答,使用类型化的 foreach 减少该集合,最后使用 GSON 进行 JSON 编码,我认为这绝对没有问题。

于 2012-11-20T01:15:41.667 回答