11

単一のMySQLselectクエリから、2つの結合されたテーブルからすべての情報を階層的に取得するための最良かつ最も洗練された方法は何でしょうか?

私はそれらの2つのテーブルを持っています:

-----------------         ------------------
| 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;

問題:jsonフラグメントを作成するための醜いforeachタイプのコードがたくさん残っています

「解決策」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フラグメントであり、company.idとnameをjsonifyするだけで済みます。しかし、mysqlでjsonフラグメントをビルドすることは非常に悪い習慣のようです。

洞察、または他の解決策はありますか?

どうもありがとう

4

2 に答える 2

2

私はおそらくあなたのソリューション1のようなクエリを使用します。会社が前と同じである場合、「company.idで並べ替え」を追加し、テーブルを1回ループして、各行のデータ構造を構築します。 1つは、従業員データを会社にプッシュすることです。もう1つは、新しい会社を定義し、それを使用して従業員データをプッシュすることです。

カルロス・キハノのように、ここではforeachの混乱は見られません。(ただし、並べ替えを行うと、処理がはるかに簡単になります)

于 2012-10-30T11:55:19.440 に答える
1

単一のMySQLクエリを実行する必要があり、醜いfor-each-typeコードをいじりたくない場合は、おそらく非階層のJSON結果を返す必要があります。クエリ結果をシリアル化することで、コードに優雅さを加えることができます。 DbUtilsクエリを使用してコレクションに追加します。

QueryRunner run = 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 に答える