hibernate SqlType.JSON (json data) 사용해 보기
Java entitiy domain에서 특정 class나 map으로 db의 json 데이터를 바인딩하여 사용할 수 있다.
Java domain class에 변경 사항이나 추가 사항을 계속 추가하면서 db에 조금씩 column을 수정/추가하는 것보다
db의 json data 저장 column 하나에 가변적으로 값을 계속 추가하여
java 쪽 entitiy class에선 json domain class의 최소한의 수정이나 map에서 변경되거나 추가된 값을 호출하여 사용하는 식으로 관리할 수 있다.
Java Entity Domain Entity JSON type 선언
https://bootify.io/spring-data/hibernate-json-type.html
Hibernate 6.0 이상에선 json type을 지원한다.
(Spring Boot 3.0.0 이상이라 이미 2022년 12월 이후 버전 사용 시엔 사용 가능하다.)
java entity domain에 해당 타입을 다음과 같이 @JdbcTypeCode
annotation에 SqlTypes.JSON
으로 선언하면 된다.
@Entity
public class SomeDomain {
// ... 생략
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, String> jsonConfig;
}
db table 생성
mariadb의 경우 Create Table Schema에 JSON으로 선언하여 생성하면
CREATE TABLE SomeTable (
// .. 중간 생략
someJsonColumn JSON
)
LONGTEXT
데이터 유형에 json_valid('column')
제약 조건으로 column을 생성한 것과 동일하다.
CREATE TABLE SomeTable (
// .. 중간 생략
someJsonColumn longtext,
CONSTRAINT `CK_SomeTable` CHECK (json_valid(`someJsonColumn`))
)
해당 테이블에 json 데이터를 저장할 수 있다.
저장해 보기
기존 저장과 달라지는 부분은 없다.
다만 java에서 map에 담긴 필드 값이 db에서는 json 형태로 저장된다.
var jsonConfig = Map.of("key1", "value1", "key2", "value2");
someDomain.setJsonConfig(jsonConfig);
someDomainRepository.create(someDomain);
// DB의 jsonConfig columne에 다음과 같은 값이 저장됨
{"key1":"value1","key2":"value2"}
Map 뿐만 아니라 custom Object로 구성하는 것도 가능하다.
public class SomeDomain {
// ... 생략
@JdbcTypeCode(SqlTypes.JSON)
private JsonConfig jsonConfig;
@Data
public static class JsonConfig {
String key1;
String key2;
String key3;
}
}
특정 class로 정의하더라도 db엔 앞서 map으로 정의한 것과 동일하게 JSON column이 생성된다.
spring.jpa.hibernate.ddl-auto=true
시 생성되는 table schema 엔 Map/ custom Object 두 경우 모두 longtext
에 json_valid
제약 조건이 처리되어 db입장에선 차이가 없다.
(ddl-auto
를 사용하지 않더라도 longtext
에 json_valid
제약 조건으로 column을 생성하여 사용하면 된다.)
Map/ Object 둘 다
- 잘 저장/조회가 되고
- 이후 data에 새로운 키/값이 추가되더라도 기존 db에 저장된 데이터 조회 시 추가된 값은 기본값 처리 (null, 0)를 해서 값 추가에 대한 추가 이슈는 없다.
(라이브 서비스엔 이 부분이 장점이 되지 않을까 싶다.)
json 형태의 데이터 관리 방법이 가장 좋은 방법이라기 보단 이런 방법도 있으니 필요한 경우 적절하게 사용하면 좋을 듯싶다.