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


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과 함께 일반 데이터까지 가지의 값을 가져 와야하기 때문에 자주 사용한다.


MySQL 5.7.8 VER 부터 JSON TYPE을 지원해준다. 

그래서 MySQL에서 JSON TYPE을 위한 많은 함수를 제공해준다.


MySQL에서는  JSON Functions의 레퍼런스를 상세히 제공해준다.


MySQL 5.7 : https://dev.mysql.com/doc/refman/5.7/en/json-functions.html
MySQL 8 : https://dev.mysql.com/doc/refman/8.0/en/json.html

아주 기본적인 예만 한번 해본다.

1.TEST라는 이름을 가진 테이블안에 아래와 같은 2개의 데이터가 들어가 있다.


2.  MySQL 레퍼런스에서 제공해주는 JSON_OBJECT라는 Function을 사용하면

아래와 같은 결과를 얻을 수 있다.



{
    "ID":  1,
     "NAME":  "TEST",
     "PASSWORD":  "1234",
     "PHONE_NUM":  "010-1111-1111"
}{
    "ID":  2,
     "NAME":  "HI",
     "PASSWORD":  "5555",
     "PHONE_NUM":  "010-2222-2222"
}


+ Recent posts