먼저 이 글을 보기 전에 알고 있으면 더 좋은 글입니다.


1번. MySQL JSON DATA TYPE

2018/11/30 - [Develop/MySQL] - [MySQL] MySQL JSON - MySQL 5.7 JSON Functions



2번. MySQL에서의 '일반' 값을 JSON형식으로 가져오기

2018/10/28 - [Develop/Spring Boot] - Spring boot JPA EntityManager를 이용한 Map형식으로 mapping하기

2018/10/24 - [Develop/Spring Boot] - Spring boot jpa map, hashmap, JSON형식


3번. JSON PARSING

2018/11/13 - [Develop/Spring Boot] - Spring Boot Json, hashmap to json , JsonObject 만들기- JSON 마지막

2018/11/12 - [Develop/Spring Boot] - Spring Boot Deserialization Json, Deserialization JsonString to JsonObject - Json 4편

2018/11/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편

2018/11/07 - [Develop/Spring Boot] - Spring Boot Json, Gson을 이용한 JsonObject to String, String to JsonObject- JSON 2편

2018/11/06 - [Develop/Spring Boot] - Spring Boot Json, JsonObject로 만들기 - JSON 1편



나도 SPRING BOOT 에서 어떻게 가져오는지 많이 검색해봤으나. 자료가 거의 없어서 열심히 삽질했던 것 같다.

수 많은 삽질 끝에 알아내서 필요한 곳에 사용중이다.


이번 글은 MySQL에서 SELECT시 일반 DATA 형식이 아닌 JSON DATA TYPE을 SPRING BOOT 에 SELECT하는 내용이다.

우선 일반 DATA형식은 그냥 말그대로 SELECT id, name FROM test 해서 가져오는 내용들이고

JSON DATA TYPE 형식은 위의 1번 링크에서 확인할 수 있다.



1. 우선 이번에 사용할 예제 테이블 및 데이터이다. 1번링크에서 확인 가능하다.



2. 먼저 JSON DATA TYPE을 불러올 코드를 작성한다.


아래의 코드를 보면 CONCAT_WS('\\\\',  부분이 있다.


사실 JSON DATA TYPE을 가져올 때 JSON_OBJECT를 사용하면 가져올 수 있으나. 사용하는 이유는


SPRING BOOT에서 CONCAT_WS('\\\\',  를 사용하지 않으면 MySQL에서 값을 불러올때 쌍따옴표를 지워버린다. 


그래서 만약 CONCAT_WS를 사용하지않고 JSON_OBJECT만을 이용하여 SELECT하면


ex) {"ID": 1, "NAME": "TEST", "PASSWORD": "1234", "PHONE_NUM": "010-1111-1111"} 이렇게 불러와야할 값이

     {"    이렇게 나오고 뒤의 내용은 다 짤려버린다.


그래서 CONCAT_WS 함수를 이용하여 쌍따옴표가 안짤리고 SELECT하기 위해 앞에 역슬래쉬를 붙인다. 


4개 붙이는 이유는 두개 붙이니까 SPRING BOOT단에서 짤려버리더라...... 그래서 4개 붙인다.


그리고 CONCAT_WS를 사용하면 값을 Byte로 불러온다.  그래서 String 형식이나 기타 외의 데이터로는 불러오지 못하므로


항상 Object 데이터 형식을 사용해서 불러와야 한다. 그 후 Object를 Byte로 변환 그리고 Byte를  String으로 변환하는 방법 등을 사용 해야 한다.


아래의 코드에서도 우선 List로 결과를 불러오고 Object를 통해 Byte로 변환 그리고 Byte를 다시 String으로 변환한다.


@GetMapping("/test")
	public void test() {
		Query query = entityManager.createNativeQuery("SELECT " + "concat_ws('\\\\', "
				+ "json_object('id', t.id, 'password', t.password, 'name', t.name, 'phone_num', t.phone_num)) "
				+ "as TEST " + "FROM " + "test t");

		List r = query.getResultList();
		for (Object obj : r) {
			byte[] b = (byte[]) obj;
			String value = new String(b, StandardCharsets.UTF_8);
			System.out.println(value);
		}
}


위 코드를 실행하면 아래와 같은 JSON 타입의 내용을 Spring Boot에서 불러올 수 있다.




3.  이 Json String을 JsonObject로 만들어보자 


3번 링크의 Gson이나 Jackson, JsonObject 등등 을 이용하여 만들 수 있다.


Jackson을 이용하여 한번 만들어 보겠다.


먼저 TestDTO 클래스를 하나 만든다 

3번링크의 Json 1편의 DTO에서 password와 phone_num 변수를 추가한다.


만든 후 현재 데이터를 2개가 불러오기 때문에 객체 배열로 생성하였다.

그 후 각 클래스 배열마다 Jackson의 objectmapper를 사용하여 Json String을 Json Object로 변환시켜주었다.


Query query = entityManager.createNativeQuery("SELECT " + "concat_ws('\\\\', "
				+ "json_object('id', t.id, 'password', t.password, 'name', t.name, 'phone_num', t.phone_num)) "
				+ "as TEST " + "FROM " + "test t");


		List r = query.getResultList();
		
		ObjectMapper objectMapper = new ObjectMapper();
		TestDTO t[] = new TestDTO[r.size()];
		int i=0;
		
		for (Object obj : r) {
			byte[] b = (byte[]) obj;
			String value = new String(b, StandardCharsets.UTF_8);
			try {
				
				t[i]= objectMapper.readValue(value, TestDTO.class);
				i++;
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
		for(TestDTO test : t) {
			System.out.println(test.getId());
			System.out.println(test.getPassword());
			System.out.println(test.getName());
			System.out.println(test.getPhone_num());
			System.out.println();
		}

아래와 같이 결과가 나온다


이것을 많은 형식을 이용하여 불러 올 수있다 2번링크를 사용하여 애초에  Map으로 불러와서 mapping시키거나 할 수 있다.


Map으로 불러와서 mapping할 경우 문제점은 정규식을 통해 파싱해줘야 하는 단점이있다.


왜냐하면 Json값이 { "id" : 1 } 이렇다면 Map으로 불러올경우 "{ "id" : 1 }" 이렇게 중괄호에 쌍따옴표가 붙어버린다.


그래서 정규식을 통해 중괄호의 쌍따옴표만 지워야 하는 단점이 있다. 하지만 나는 이러한 단점에도 불구하고도 


JSON_TYPE과 함께 일반 데이터까지 가지의 값을 가져 와야하기 때문에 자주 사용한다.


마지막으로 hashmap 을 json으로 만드는 방법과, JsonObject를 생성하는 방법이다.



Spring boot Json 1편, 2편, 3편, 4편

1. 2018/11/06 - [Spring Boot] - Spring Boot Json, JsonObject로 만들기 - JSON 1편

2. 2018/11/07 - [Develop/Spring Boot] - Spring Boot Json, Gson을 이용한 JsonObject to String, String to JsonObject- JSON 2편

3. 2018/11/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편

4. 2018/11/12 - [Develop/Spring Boot] - Spring Boot Deserialization Json, Deserialization JsonString to JsonObject - Json 4편



번외 Database의 값을 Json으로 select하는 방법.

1. 2018/10/24 - [Spring Boot] - Spring boot jpa map, hashmap, JSON형식

2. 2018/10/28 - [Spring Boot] - Spring boot JPA EntityManager를 이용한 Map형식으로 mapping하기


Spring boot에서 MySQL JSON 타입 SELECT하는 방법

1. 2018/11/30 - [Develop/Spring Boot] - Spring boot MySQL JSON - MySQL JSON DATA TYPE 값 가져오기



HashMap을 Json으로 만드는 방법을 배우기에 앞서 JsonObject를 생성하는 방법을 먼저 본다.


1. google-json-simple을 이용한 JsonObject 만드는 방법.


xml에 아래와 같은 dependency를 추가한다.


		com.googlecode.json-simple
		json-simple
		1.1


우리가 만들어볼 Json예제는 4편에서 사용한 Json이다.


{
    "id": 1,
    "password": "1234",
    "details": [
        {
            "name": "test",
            "age": 20
        },{
            "name": "test2",
            "age": 21
        }
    ] 
}

그리고 아래와 같이 JSONObject라는 것과 JSONArray라는 것을 사용하여 JSON을 생성할 수 있다.


public void test() {
		JSONObject obj = new JSONObject();
		JSONArray arr = new JSONArray();
		
		obj.put("id", 1);
		obj.put("password", "1234");
		
		JSONObject obj2 =new JSONObject();
		obj2.put("name", "test");
		obj2.put("age", 20);
		
		arr.add(obj2);
		
		obj2 = new JSONObject();
		obj2.put("name", "test2");
		obj2.put("age", 21);
		
		arr.add(obj2);
		
		obj.put("details", arr);
		
		System.out.println(obj.toString());
		
}




현재는 Json이 Array를 포함하여 JSONArray를 사용하였지만 일반 적인 key : value 형태는 JSONObject 하나만으로도 생성할 수 있다.


2. Gson을 이용한JsonObject 생성


이 방법은 Json  2편에서 배웠으나 이번엔 Array를 사용하기 때문에 다시 한번 해본다. 사실 위의 json-simple과 별반 다를게 없다.



	public void test() {
		Gson gson = new Gson();
		JsonObject obj = new JsonObject();
		JsonArray arr = new JsonArray();
		
		obj.addProperty("id", 1);
		obj.addProperty("password", "1234");
		
		JsonObject obj2 = new JsonObject();
		obj2.addProperty("name", "test");
		obj2.addProperty("age", 20);
		arr.add(obj2);
		
		obj2= new JsonObject();
		obj2.addProperty("name", "test2");
		obj2.addProperty("age", 21);
		
		arr.add(obj2);
		
		obj.add("details", arr);
		
		String jsonString = obj.toString();
		
		System.out.println("gson을 이용한 객체생성");
		System.out.println(jsonString);
		
	}




3. HashMap을 Json으로 만드는 방법.


HashMap<String, Object>를 선언해서 이번 편에서 했던 모든 것들(json-simple의 obj와 gson의 obj)을 HashMap에 put해보고

일반 데이터를 HashMap에 put해서 json으로 변환해 보는 법을 해본다. 그리고 gson의 prettyprinting을 이용하여 예쁘게 출력해본다.



public void test() {
		JSONObject obj = new JSONObject();
		JSONArray arr = new JSONArray();

		obj.put("id", 1);
		obj.put("password", "1234");

		JSONObject obj2 = new JSONObject();
		obj2.put("name", "test");
		obj2.put("age", 20);

		arr.add(obj2);

		obj2 = new JSONObject();
		obj2.put("name", "test2");
		obj2.put("age", 21);

		arr.add(obj2);

		obj.put("details", arr);

		
		JsonObject g_obj = new JsonObject();
		JsonArray g_arr = new JsonArray();

		g_obj.addProperty("id", 1);
		g_obj.addProperty("password", "1234");

		JsonObject g_obj2 = new JsonObject();
		g_obj2.addProperty("name", "test");
		g_obj2.addProperty("age", 20);
		g_arr.add(g_obj2);

		g_obj2 = new JsonObject();
		g_obj2.addProperty("name", "test2");
		g_obj2.addProperty("age", 21);

		g_arr.add(g_obj2);

		g_obj.add("details", g_arr);
		
		HashMap map = new HashMap();
		map.put("json-simple", obj);
		map.put("gson", g_obj);
		map.put("HashMap", "맵테스트");
		map.put("숫자테스트", 1234567890);
		
		Gson gson = new GsonBuilder().setPrettyPrinting().create();
		String jsonString = gson.toJson(map, new TypeToken>() {
		}.getType());
		System.out.println("HashMap to JSON");
		System.out.println(jsonString);

	}



이로써 Spring boot 에서의 Json에 대한 학습을 마무리한다.

1편부터 마지막편까지의 내용과 번외편 내용 2개만 알아도 Spring boot에서 모든 데이터들을 Json으로 만들 수 있다.


어찌보면 가장 중요한 Deserialization한 JsonString 형태를 파싱하는 방법이다.

Spring Boot에서 Deserialization 파싱을 위해 Jackson과 gson을 사용하면서 동시에 클래스를 생성하여 사용해야한다.



Spring boot Json 1편, 2편, 3편, 마지막

1. 2018/11/06 - [Spring Boot] - Spring Boot Json, JsonObject로 만들기 - JSON 1편

2. 2018/11/07 - [Develop/Spring Boot] - Spring Boot Json, Gson을 이용한 JsonObject to String, String to JsonObject- JSON 2편

3. 2018/11/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편

4. 2018/11/13 - [Develop/Spring Boot] - Spring Boot Json, hashmap to json , JsonObject 만들기- JSON 마지막



번외 Database의 값을 Json으로 select하는 방법.

1. 2018/10/24 - [Spring Boot] - Spring boot jpa map, hashmap, JSON형식

2. 2018/10/28 - [Spring Boot] - Spring boot JPA EntityManager를 이용한 Map형식으로 mapping하기


Spring boot에서 MySQL JSON 타입 SELECT하는 방법

1. 2018/11/30 - [Develop/Spring Boot] - Spring boot MySQL JSON - MySQL JSON DATA TYPE 값 가져오기



1. Class를 생성하여 Gson을 이용한 Deserializaion한 JsonString to Object(JsonObject)


앞의 1편, 2편, 3편에 사용했던 TestDTO를 수정하자.


수정하기 전 먼저 Test_2DTO를 새로 생성한다


public class Test_2DTO {
	private String name;
	private int age;
	
	public Test_2DTO() {
		super();
	}

	public Test_2DTO(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}
public class TestDTO {

	private Integer id;
	private String password;
	private List details;
	
	
	public TestDTO() {
		super();
	}


	public TestDTO(Integer id, String password, List details) {
		super();
		this.id = id;
		this.password = password;
		this.details = details;
	}


	public Integer getId() {
		return id;
	}


	public void setId(Integer id) {
		this.id = id;
	}


	public String getPassword() {
		return password;
	}


	public void setPassword(String password) {
		this.password = password;
	}


	public List getDetails() {
		return details;
	}


	public void setDetails(List details) {
		this.details = details;
	}


	@Override
	public String toString() {
		return new Gson().toJson(this);
	}
}


생성했다면, 


public void test() {
		
		String jsonString = "{\r\n" + 
				"    \"id\": 1,\r\n" + 
				"    \"password\": \"1234\",\r\n" + 
				"    \"details\": [\r\n" + 
				"        {\r\n" + 
				"            \"name\": \"test\",\r\n" + 
				"            \"age\": 20\r\n" + 
				"        },{\r\n" + 
				"            \"name\": \"test2\",\r\n" + 
				"            \"age\": 21\r\n" + 
				"        }\r\n" + 
				"    ] \r\n" + 
				"}";
		Gson gson = new Gson();
		TestDTO t = gson.fromJson(jsonString, TestDTO.class);
		System.out.println("id : " +t.getId());
		System.out.println("password : "+t.getPassword());
		System.out.println("name1 : "+t.getDetails().get(0).getName());
		System.out.println("age1: "+t.getDetails().get(0).getAge());
		System.out.println("name2 : "+t.getDetails().get(1).getName());
		System.out.println("age2: "+t.getDetails().get(1).getAge());
		
	}

위에 사용한 Json내용이다., 


{
    "id": 1,
    "password": "1234",
    "details": [
        {
            "name": "test",
            "age": 20
        },{
            "name": "test2",
            "age": 21
        }
    ] 
}


위 test() 메소드를 실행하면 아래와 같이 Deserializaion한 JsonString이 파싱되어 JsonObject에 알맞게 들어간다.



2. Jackson의 ObjectMapper를 이용한 Json String to JsonObject 이다.


Json내용은 위와 동일한 상태에서 진행하였다.


public void test() {
		ObjectMapper objectMapper = new ObjectMapper();
		 
		String jsonString = "{\r\n" + 
				"    \"id\": 1,\r\n" + 
				"    \"password\": \"1234\",\r\n" + 
				"    \"details\": [\r\n" + 
				"        {\r\n" + 
				"            \"name\": \"test\",\r\n" + 
				"            \"age\": 20\r\n" + 
				"        },{\r\n" + 
				"            \"name\": \"test2\",\r\n" + 
				"            \"age\": 21\r\n" + 
				"        }\r\n" + 
				"    ] \r\n" + 
				"}";
		  try {
	            TestDTO t = objectMapper.readValue(jsonString, TestDTO.class);    // String to Object로 변환
	            System.out.println("ObjectMapper테스트");
	    		System.out.println("id : " +t.getId());
	    		System.out.println("password : "+t.getPassword());
	    		System.out.println("name1 : "+t.getDetails().get(0).getName());
	    		System.out.println("age1: "+t.getDetails().get(0).getAge());
	    		System.out.println("name2 : "+t.getDetails().get(1).getName());
	    		System.out.println("age2: "+t.getDetails().get(1).getAge());	     
	
	        } catch (IOException e) {
	            e.printStackTrace();
	        }		
}

gson과 마찬가지로 잘 작동된다.


3. Jackson JsonNode 를 이용한 Deserializaion String to JsonObject


어떻게 보면 가장 핵심인 부분일 수도 있다. 클래스 생성없이 할 수 있다는 큰 장점이있다.


Deserializaion Json Data는 위와 동일한 데이터를 사용한다.



public void test() {
		ObjectMapper objectMapper = new ObjectMapper();

		String jsonString = "{\r\n" + "    \"id\": 1,\r\n" + "    \"password\": \"1234\",\r\n"
				+ "    \"details\": [\r\n" + "        {\r\n" + "            \"name\": \"test\",\r\n"
				+ "            \"age\": 20\r\n" + "        },{\r\n" + "            \"name\": \"test2\",\r\n"
				+ "            \"age\": 21\r\n" + "        }\r\n" + "    ] \r\n" + "}";
		try {
			System.out.println("Jackson JsonNode 테스트");
			JsonNode t = objectMapper.readValue(jsonString, JsonNode.class); // String to Object로 변환
			
			JsonNode id = t.get("id");
			System.out.println("id : " + id.asInt());
			
			JsonNode password = t.get("password");
			System.out.println("password : " + password.asText());
			
			JsonNode details = t.get("details");
			JsonNode details_1 = details.get(0);		
			System.out.println("name1 : " + details_1.get("name").asText());
			System.out.println("age1: " + details_1.get("age").asInt());
			
			JsonNode details_2 = details.get(1);	
			System.out.println("name2 : " + details_2.get("name").asText());
			System.out.println("age2: " + details_2.get("name").asText());

		} catch (IOException e) {
			e.printStackTrace();
		}
}

class 생성없이 파싱이 잘 되었다


이 처럼 웬만한 것들은 class를 생성하여 모든 Deserializaion을 파싱할 수 있으며,

Jackson JsonNode 를 이용하여 처리할 수 있다. 


Spring Boot에서 데이터를 JSON형식으로 표현하는 가장 기본적인 방법으로는 클래스를 이용하는 방법이다.

이 방법을 알아야 다음에 Deserialization한 JSON을 만들 수 있다.


Spring boot Json 2편, 3편, 4편, 마지막

1. 2018/11/07 - [Develop/Spring Boot] - Spring Boot Json, Gson을 이용한 JsonObject to String, String to JsonObject- JSON 2편

2. 2018/11/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편

3. 2018/11/12 - [Develop/Spring Boot] - Spring Boot Deserialization Json, Deserialization JsonString to JsonObject - Json 4편

4. 2018/11/13 - [Develop/Spring Boot] - Spring Boot Json, hashmap to json , JsonObject 만들기- JSON 마지막


번외 Database의 값을 Json으로 select하는 방법.

1. 2018/10/24 - [Spring Boot] - Spring boot jpa map, hashmap, JSON형식

2. 2018/10/28 - [Spring Boot] - Spring boot JPA EntityManager를 이용한 Map형식으로 mapping하기


Spring boot에서 MySQL JSON 타입 SELECT하는 방법

1. 2018/11/30 - [Develop/Spring Boot] - Spring boot MySQL JSON - MySQL JSON DATA TYPE 값 가져오기




먼저 DTO를 생성한다.

public class TestDTO {

	private Integer id;
	private String password;
	
	
	public TestDTO() {
		super();
	}
	public TestDTO(Integer id, String password) {
		super();
		this.id = id;
		this.password = password;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}
다음 컨트롤러를 하나 생성해준다.
@RestController
@RequestMapping(value = "/jsontest")
public class TestClass {
	
	@GetMapping()
	public TestDTO test() {
		TestDTO test = new TestDTO(1, "1111");
		return test;
	}
	
	@GetMapping("/2")
	public List test2() {
		List test = new ArrayList();
		test.add(0, new TestDTO(1, "1111"));
		test.add(1, new TestDTO(2, "2222"));
		test.add(2, new TestDTO(3, "3333"));
		return test;
	}
}


그리고 실행하게 되면


1. test() 실행화면


2. test2() 실행화면

이렇게 Json 형태로 출력된다

참고로 Map은 Json형태로 출력되지 않고 {"id" = 1, "password"="1111"} 형식으로 출력된다. List만 Json형식으로 출력된다.

또한, 이렇게 클래스로 만든 JsonObject는 Return할 때만 Json으로 출력되지, log또는 print할 경우엔 Json형식으로 출력되지 않는다.

Json형식으로 출력되게 하려면 다음에 할 2편을 참고.


기초는 마무리.


+ Recent posts