2016-12-31 12 views
1

私はJavaの初心者です。 JDBCテンプレートを使用してSQL Serverからデータを取得して結合しています。 受信したデータをグループ化します。JavaでSQLクエリから処理されたデータを処理してグループ化する方法は?

processId processName subId subName valueId value gId gradeName 
1   p1   1  s1  11  v1 1  g1 
1   p1   1  s1  11  v1 2  g2 
2   p2   2  s2  null null null null 
3   p3   3  s3  13  v3 null null 

そして、私が欲しいの出力を以下:私はリンク質問で述べたように、出力を反復するためにループしながら、使用されるが、私はできないのですlink

[{ 
    "processId": 1, 
    "processname": "p1", 
    "sub": [{ 
     "subId": 11, 
     "subName": "s1", 
     "value": [{ 
      "valueId": 11, 
      "value": "v1", 
      "grades": [{ 
       "gId": 1, 
       "gradeName": "g1" 
      }, { 
       "gId": 2, 
       "gradeName": "g2" 
      }] 
     }] 
    }] 
}, { 
    "processId": 2, 
    "processname": "p2", 
    "sub": [{ 
     "subId": 12, 
     "subName": "s2", 
     "value": [] 
    }] 
}, { 
    "processId": 3, 
    "processname": "p3", 
    "sub": [{ 
     "subId": 13, 
     "subName": "s3", 
     "value": [{ 
      "valueId": 3, 
      "value": "g3", 
      "grade": [] 
     }] 
    }] 
}] 

私はここに同様の質問を見つけましたそうするために。

ハッシュマップを使用するコメントのユーザー状態の1つですが、ハッシュマップを実装できません。それについて誰かが私を導くことができますか?

誰も私がこれを整理するのを手伝ったり助けたりできますか?

答えて

1

これを実行する方法はたくさんありますが、次のような方法があります。

まず、あなたの結果を構造化するモデルを作成:

@JsonSerialize(using = MapAsListSerializer.class)

MapAsListSerializer:

package core.map; 

import java.util.HashMap; 
import java.util.Map; 

import com.fasterxml.jackson.databind.annotation.JsonSerialize; 

public class Process { 
    private String processId; 
    private String processName; 

    @JsonSerialize(using = MapAsListSerializer.class) 
    private Map<String, Sub> sub = new HashMap<>(); 

    public Process(final String processId, final String processName) { 
     this.processId = processId; 
     this.processName = processName; 
    } 

    public String getProcessId() { 
     return processId; 
    } 

    public String getProcessName() { 
     return processName; 
    } 

    public Map<String, Sub> getSub() { 
     return sub; 
    } 

    static class Sub { 
     private String subId; 
     private String subName; 

     @JsonSerialize(using = MapAsListSerializer.class) 
     private Map<String, Value> value = new HashMap<>(); 

     public Sub(final String subId, final String subName) { 
      this.subId = subId; 
      this.subName = subName; 
     } 

     public String getSubId() { 
      return subId; 
     } 

     public String getSubName() { 
      return subName; 
     } 

     public Map<String, Value> getValue() { 
      return value; 
     } 

     static class Value { 
      private String valueId; 
      private String value; 

      @JsonSerialize(using = MapAsListSerializer.class) 
      private Map<String, Grade> grades = new HashMap<>(); 

      public Value(final String valueId, final String value) { 
       this.valueId = valueId; 
       this.value = value; 
      } 

      public String getValueId() { 
       return valueId; 
      } 

      public String getValue() { 
       return value; 
      } 

      public Map<String, Grade> getGrades() { 
       return grades; 
      } 

      static class Grade { 
       private String gId; 
       private String gradeName; 

       public Grade(final String gId, final String gradeName) { 
        this.gId = gId; 
        this.gradeName = gradeName; 
       } 

       public String getgId() { 
        return gId; 
       } 

       public String getGradeName() { 
        return gradeName; 
       } 

      } 
     } 
    } 
} 

これは、行を除いて(多かれ少なかれ)簡単なPOJOの、のちょうど束でした必要に応じて最終結果を表示するためのちょっとしたカスタムJsonシリアライザです(マップの代わりにフラットリスト)。

package core.map; 

import java.io.IOException; 
import java.util.Map; 

import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.JsonSerializer; 
import com.fasterxml.jackson.databind.SerializerProvider; 

public class MapAsListSerializer extends JsonSerializer<Map<?, ?>> { 

    @Override 
    public void serialize(Map<?, ?> incomingMap, JsonGenerator generator, SerializerProvider arg2) 
      throws IOException, JsonProcessingException { 
     generator.writeObject(incomingMap.values()); 

    } 
} 

少なくとも我々は(偽のデータベース)の結果を計算するためのコードを必要とする、このようなものが考えられます。

package core.map; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

import core.map.Process.Sub; 
import core.map.Process.Sub.Value; 
import core.map.Process.Sub.Value.Grade; 

public class ResultMapper { 

    private final static ObjectMapper mapper = new ObjectMapper(); 

    private final static List<List<String>> resultSet = new ArrayList<>(); 

    private final static Map<String, Process> processes = new HashMap<>(); 

    static { 
     resultSet.add(Arrays.asList("1", "p1", "1", "s1", "11", "v1", "1", "g1")); 
     resultSet.add(Arrays.asList("1", "p1", "1", "s1", "11", "v1", "2", "g2")); 
     resultSet.add(Arrays.asList("2", "p2", "2", "s2", null, null, null, null)); 
     resultSet.add(Arrays.asList("3", "p3", "3", "s3", "13", "v3", null, null)); 
    } 

    public static void main(String[] args) throws JsonProcessingException { 
     resultSet.forEach(row -> rowToProcess(row, processes)); 
     System.out.println(mapper.writeValueAsString(processes.values())); 
    } 

    private static void rowToProcess(final List<String> row, final Map<String, Process> processes) { 

     final String processId = row.get(0); 
     final String processName = row.get(1); 
     final String subId = row.get(2); 
     final String subName = row.get(3); 
     final String valueId = row.get(4); 
     final String value = row.get(5); 
     final String gId = row.get(6); 
     final String gradeName = row.get(7); 

     Process currentProcess = processes.get(processId); 
     if (currentProcess == null) { 
      currentProcess = new Process(processId, processName); 
      processes.put(processId, currentProcess); 
     } 

     Map<String, Sub> subs = currentProcess.getSub(); 
     Sub currentSub = subs.get(subId); 
     if (currentSub == null) { 
      currentSub = new Process.Sub(subId, subName); 
      subs.put(subId, currentSub); 
     } 

     Map<String, Value> values = currentSub.getValue(); 
     if (valueId == null) 
      return; 
     Value currentValue = values.get(valueId); 
     if (currentValue == null) { 
      currentValue = new Sub.Value(valueId, value); 
      values.put(valueId, currentValue); 
     } 

     if (gId == null) 
      return; 
     Map<String, Grade> grades = currentValue.getGrades(); 
     grades.put(gId, new Value.Grade(gId, gradeName)); 
    } 
} 

だから、ほぼすべては、JSONを除き、JDK(1.8)の外にあります依存関係。すべての必要な余分なものが利用可能here

拡張したものです。もちろん

それはあなたがジャクソンの処理のためだけに必要なゲッターを省略することができ、可能です。それは(ゲッターなし)のようなものになるでしょう:

package core.map; 

import java.util.HashMap; 
import java.util.Map; 

import com.fasterxml.jackson.databind.annotation.JsonSerialize; 

public class Process { 
    private String processId; 
    private String processName; 

    @JsonSerialize(using = MapAsListSerializer.class) 
    private Map<String, Sub> sub = new HashMap<>(); 

    public Process(final String processId, final String processName) { 
     this.processId = processId; 
     this.processName = processName; 
    } 

    public Map<String, Sub> getSub() { 
     return sub; 
    } 

    static class Sub { 
     private String subId; 
     private String subName; 

     @JsonSerialize(using = MapAsListSerializer.class) 
     private Map<String, Value> value = new HashMap<>(); 

     public Sub(final String subId, final String subName) { 
      this.subId = subId; 
      this.subName = subName; 
     } 

     public Map<String, Value> getValue() { 
      return value; 
     } 

     static class Value { 
      private String valueId; 
      private String value; 

      @JsonSerialize(using = MapAsListSerializer.class) 
      private Map<String, Grade> grades = new HashMap<>(); 

      public Value(final String valueId, final String value) { 
       this.valueId = valueId; 
       this.value = value; 
      } 

      public Map<String, Grade> getGrades() { 
       return grades; 
      } 

      static class Grade { 
       private String gId; 
       private String gradeName; 

       public Grade(final String gId, final String gradeName) { 
        this.gId = gId; 
        this.gradeName = gradeName; 
       } 

      } 
     } 
    } 
} 

しかし、その後、あなたはフィールドに直接の代わりにゲッターを使用するためにジャクソンを伝える必要があります:

mapper.setVisibility(PropertyAccessor.GETTER, Visibility.NONE); 
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); 

ことがありますので、私はここで両方のソリューションを維持します個人的な好みについての何か。もちろん、Processクラスを省略して、それに似たものを書くこともできますが、何らかの形でデータを構造化する必要があります。

+0

回答ありがとうございます。ゲッター/セッターを使わなくても可能ですか?私はあなたが使った 'processes'クラスを使いたくありません。 – Joe

+0

あなたの質問に関する私の答えを調整しました。 –

関連する問題