먼저 이 글을 보기 전에 알고 있으면 더 좋은 글입니다.
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/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편
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과 함께 일반 데이터까지 가지의 값을 가져 와야하기 때문에 자주 사용한다.
'Develop > Spring Boot' 카테고리의 다른 글
Spring Boot, LocalDateTime Gson Serialize(JPA LocalDateTime) (0) | 2019.01.18 |
---|---|
Spring boot reCAPTCHA - Invisible reCAPTCHA (0) | 2018.12.18 |
Spring boot Slack WebHook. 슬랙 웹훅(Java Slack WebHook) (0) | 2018.11.24 |
Spring boot AWS S3 파일 업로드 (0) | 2018.11.18 |
Spring Boot Json, hashmap to json , JsonObject 만들기- JSON 마지막 (0) | 2018.11.13 |