JPA를 사용하여 JSON 열을 Java 객체에 매핑하는 방법
기둥들이 많이 있는 큰 테이블이 있습니다.MySQL 클러스터로 이동한 후 다음 이유로 테이블을 만들 수 없습니다.
ERROR 1118(42000):행 크기가 너무 큽니다.BLOB를 카운트하지 않고 사용되는 테이블타입의 최대 행 사이즈는 14000 입니다.여기에는 스토리지 오버헤드가 포함됩니다. 매뉴얼을 참조하십시오.일부 열을 TEXT 또는 BLOB로 변경해야 합니다.
예를 들어 다음과 같습니다.
@Entity @Table (name = "appconfigs", schema = "myproject")
public class AppConfig implements Serializable
{
@Id @Column (name = "id", nullable = false)
@GeneratedValue (strategy = GenerationType.IDENTITY)
private int id;
@OneToOne @JoinColumn (name = "app_id")
private App app;
@Column(name = "param_a")
private ParamA parama;
@Column(name = "param_b")
private ParamB paramb;
}
설정 파라미터를 저장하기 위한 테이블입니다.몇 개의 열을 하나로 결합하여 JSON 오브젝트로 저장하고 Java 오브젝트로 변환할 수 있을 것 같습니다.
예를 들어 다음과 같습니다.
@Entity @Table (name = "appconfigs", schema = "myproject")
public class AppConfig implements Serializable
{
@Id @Column (name = "id", nullable = false)
@GeneratedValue (strategy = GenerationType.IDENTITY)
private int id;
@OneToOne @JoinColumn (name = "app_id")
private App app;
@Column(name = "params")
//How to specify that this should be mapped to JSON object?
private Params params;
}
여기서 정의:
public class Params implements Serializable
{
private ParamA parama;
private ParamB paramb;
}
이를 통해 모든 열을 하나로 결합하여 테이블을 만들 수 있습니다.아니면 전체 테이블을 여러 개의 테이블로 나눌 수도 있습니다.개인적으로 나는 첫 번째 해결책을 선호한다.
아무튼 자바 객체의 JSON 문자열을 포함하는 텍스트인 Params 열을 어떻게 매핑할 것인가?
JPA 변환기를 사용하여 엔티티를 데이터베이스에 매핑할 수 있습니다.다음과 같은 주석을 매개 변수 필드에 추가하십시오.
@Convert(converter = JpaConverterJson.class)
그런 다음 비슷한 방법으로 클래스를 만듭니다(이것에 의해 범용 오브젝트가 변환됩니다.특화시킬 수도 있습니다).
@Converter(autoApply = true)
public class JpaConverterJson implements AttributeConverter<Object, String> {
private final static ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(Object meta) {
try {
return objectMapper.writeValueAsString(meta);
} catch (JsonProcessingException ex) {
return null;
// or throw an error
}
}
@Override
public Object convertToEntityAttribute(String dbData) {
try {
return objectMapper.readValue(dbData, Object.class);
} catch (IOException ex) {
// logger.error("Unexpected IOEx decoding json from database: " + dbData);
return null;
}
}
}
이상입니다. 이 클래스를 사용하여 테이블 내의 모든 개체를 json으로 직렬화할 수 있습니다.
JPAAttributeConverterJSON 오브젝트유형을 매핑하기에는 너무 한정되어 있습니다.특히 JSON 바이너리로 저장하는 경우에는 더욱 그렇습니다.
JSON 지원을 받기 위해 커스텀 휴지 타입을 작성할 필요는 없습니다.필요한 것은 휴지 타입 OSS 프로젝트를 사용하는 것뿐입니다.
를 들어5.2 버전을 5.2에서 .
pom.xml★★★★★★★★★<dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>${hibernate-types.version}</version> </dependency>
또는 좋은은 기본 클래스 클래스 중 .@MappedSuperclass:
@TypeDef(name = "json", typeClass = JsonType.class)
엔티티 매핑은 다음과 같습니다.
@Type(type = "json")
@Column(columnDefinition = "json")
private Location location;
.2 하고 있는 경우는, 「」5.2 「」를 해 주세요.JSON은 자동으로 됩니다.MySQL57Dialect.
그렇지 않으면 직접 등록해야 합니다.
public class MySQLJsonDialect extends MySQL55Dialect {
public MySQLJsonDialect() {
super();
this.registerColumnType(Types.JAVA_OBJECT, "json");
}
}
ㅇㅇㅇㅇ을 .hibernate.dialect MySQLJsonDialect작성하신 클래스입니다.
할 때 으로 매핑해야 할 를 들어 응답 json을 합니다(rest API).@JsonRawValue다음과 같습니다.
@Column(name = "params", columnDefinition = "json")
@JsonRawValue
private String params;
이렇게 하면 서버 측에서 DTO 매핑이 수행되지 않을 수 있지만 클라이언트는 json으로 올바른 형식의 속성을 얻을 수 있습니다.
그것은 간단하다.
@Column(name = "json_input", columnDefinition = "json")
private String field;
mysql 데이터베이스에서 열 'json_input' json 유형
코드를 너무 많이 쓰는 것을 원하지 않는 사람들을 위한 회피책이 있습니다.
프런트 엔드 -> POST 메서드에서 JSON 개체를 string base64로 인코딩하고 GET 메서드에서 json으로 디코딩합니다.
In POST Method
data.components = btoa(JSON.stringify(data.components));
In GET
data.components = JSON.parse(atob(data.components))
백엔드 -> JPA 코드에서 열을 String 또는 BLOB로 변경합니다.변환 불필요.
@Column(name = "components", columnDefinition = "json")
private String components;
이 새로운 버전의 스프링 부트 및 MySQL 아래 코드에서는 충분합니다.
@Column( columnDefinition = "json" )
private String string;
견적의 문제에 직면하고 있었기 때문에, 프로젝트의 아래 행에 코멘트를 했습니다.
#spring.jpa.properties.hibernate.globally_quoted_identifiers=true
비슷한 문제가 있어 @Externalizer 주석과 잭슨을 사용하여 데이터를 시리얼화/비직렬화함으로써 해결했습니다(@Externalizer는 OpenJPA 고유의 주석이므로 JPA 구현에 동일한 가능성을 확인해야 합니다).
@Persistent
@Column(name = "params")
@Externalizer("toJSON")
private Params params;
Params 클래스의 실장:
public class Params {
private static final ObjectMapper mapper = new ObjectMapper();
private Map<String, Object> map;
public Params () {
this.map = new HashMap<String, Object>();
}
public Params (Params another) {
this.map = new HashMap<String, Object>();
this.map.putAll(anotherHolder.map);
}
public Params(String string) {
try {
TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {
};
if (string == null) {
this.map = new HashMap<String, Object>();
} else {
this.map = mapper.readValue(string, typeRef);
}
} catch (IOException e) {
throw new PersistenceException(e);
}
}
public String toJSON() throws PersistenceException {
try {
return mapper.writeValueAsString(this.map);
} catch (IOException e) {
throw new PersistenceException(e);
}
}
public boolean containsKey(String key) {
return this.map.containsKey(key);
}
// Hash map methods
public Object get(String key) {
return this.map.get(key);
}
public Object put(String key, Object value) {
return this.map.put(key, value);
}
public void remove(String key) {
this.map.remove(key);
}
public Object size() {
return map.size();
}
}
HTH
JPA 버전 2.1 이후를 사용하고 있는 경우는, 이 케이스를 사용할 수 있습니다.링크 지속성 Json 개체
퍼블릭 클래스 HashMapConverter는 AttributeConverter <맵, 오브젝트>, String> {를 구현합니다.
@Override
public String convertToDatabaseColumn(Map<String, Object> customerInfo) {
String customerInfoJson = null;
try {
customerInfoJson = objectMapper.writeValueAsString(customerInfo);
} catch (final JsonProcessingException e) {
logger.error("JSON writing error", e);
}
return customerInfoJson;
}
@Override
public Map<String, Object> convertToEntityAttribute(String customerInfoJSON) {
Map<String, Object> customerInfo = null;
try {
customerInfo = objectMapper.readValue(customerInfoJSON,
new TypeReference<HashMap<String, Object>>() {});
} catch (final IOException e) {
logger.error("JSON reading error", e);
}
return customerInfo;
}
}
표준 JSON 개체는 다음 속성을 HashMap으로 나타냅니다.
@Convert(변환기 = HashMapConverter.class) 프라이빗 맵 <String, Object> entityAttributes;
언급URL : https://stackoverflow.com/questions/25738569/how-to-map-a-map-json-column-to-java-object-with-jpa
'programing' 카테고리의 다른 글
| 반응 선택:적어도 비동기 모드에서 목록을 펼치는 오른쪽 버튼을 삭제할 수 있는 방법이 있습니까? (0) | 2023.02.28 |
|---|---|
| 콘텐츠를 지정하는 jsonp POST 요청 작성 방법jQuery로 입력하시겠습니까? (0) | 2023.02.28 |
| Woocommerce에서 특정 제품별로 다른 크기를 표시하는 방법 (0) | 2023.02.28 |
| CSS3 멀티 컬럼리스트 (0) | 2023.02.28 |
| 각도 지시어는 지시어의 속성에 지정된 식에 있는 함수에 인수를 전달할 수 있습니까? (0) | 2023.02.28 |
