programing

프로젝트에서 MySQL과 Postgre를 모두 사용하는 경우 JsonStringType에서 JsonBinaryType으로 전환SQL

javaba 2022. 11. 5. 11:31
반응형

프로젝트에서 MySQL과 Postgre를 모두 사용하는 경우 JsonStringType에서 JsonBinaryType으로 전환SQL


Postgre에서 전환해야 할 때 열 json에 문제가 있습니다.SQL에서 MariaDB/MySql로.
Spring Boot + JPA + Hibernate + hibernate - types - 52 를 사용하고 있습니다.
매핑할 테이블은 다음과 같습니다.

CREATE TABLE atable(
 ...
 acolumn JSON,
 ... 
);

네, Postgre에 유효합니다.SQL 및 MariaDB/MySql.
문제는 Postgre의 hibernate-types-52가 올바르게 구현되어 있기 때문에 쉽게 전환할 수 있는 어플리케이션을 도입하는 경우입니다.SQL과 MySQL/MariaDB는 다르다

MySQL/MariaDB에서 작동합니다.

@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonStringType.class)
  public class Atable {
  ...
  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;
  ...
}

이것은 Posgre에서 동작합니다.SQL

@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonBinaryType.class)
public class Atable {
  ...
  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;
  ...
}

JsonBinaryType에서 JsonStringType(또는 이를 해결하기 위한 기타 솔루션)으로 전환하는 모든 종류의 솔루션에 감사드립니다.

먼저2.11휴지 상태 유형 프로젝트의 버전에서는JsonTypePostgre와 연동됩니다.SQL, MySQL, Oracle, SQL Server 또는 H2 중 하나입니다.

그럼, 을 사용해 주세요.JsonType대신JsonBinaryType또는JsonStringType

@Entity
@Table(name = "atable")
@TypeDef(name = "json", typeClass = JsonType.class)
public class Atable {

  @Type(type = "json")
  @Column(name = "acolumn", columnDefinition = "json")
  private JsonNode acolumn;

}

바로 그거야!

다음과 같은 엉뚱한 작업을 수행할 수 있습니다. 단, 이는 특정 유형 및 열에서만 작동한다는 제한이 있습니다.

우선, 스태틱을 교환합니다.@TypeDef다이나믹 매핑을 사용하는 경우:

를 사용할 수 있습니다.HibernatePropertiesCustomizer을 덧붙이다TypeContributorList:

@Configuration
public class HibernateConfig implements HibernatePropertiesCustomizer {

  @Value("${spring.jpa.database-platform:}")
  private Class<? extends Driver> driverClass;

  @Override
  public void customize(Map<String, Object> hibernateProperties) {

    AbstractHibernateType<Object> jsonType;
    if (driverClass != null && PostgreSQL92Dialect.class.isAssignableFrom(driverClass)) {
      jsonType = new JsonBinaryType(Atable.class);
    } else {
      jsonType = new JsonStringType(Atable.class);
    }

    hibernateProperties.put(EntityManagerFactoryBuilderImpl.TYPE_CONTRIBUTORS,
        (TypeContributorList) () -> List.of(
            (TypeContributor) (TypeContributions typeContributions, ServiceRegistry serviceRegistry) ->
                typeContributions.contributeType(jsonType, "myType")));
  }
}

따라서 이 기능은Atable.class이 커스텀 Json-Type을 'myType'이라고 명명했습니다.즉, 다음과 같이 속성에 주석을 붙입니다.@Type(type = 'myType').

여기서 설정된 사투리를 사용하고 있습니다만, 어플리케이션에서는 DB 고유의 프로파일에 대해 액티브한 프로파일을 체크하고 있습니다.

또, 주의해 주세요.TypeContributions .contributeType(BasicType, String...)는 휴지 상태 5.3 이후 권장되지 않습니다.저는 아직 새로운 메커니즘을 조사하지 않았습니다.

그럼 이 부분은@Type부분적이지만 휴지 상태 스키마 생성을 사용하려면@Column(columnDefinition = "...bit를 선택하면 Hibernate는 어떤 컬럼 유형을 사용할지 알 수 있습니다.

여기서부터 좀 역겹게 느껴져요.Integrator를 등록하여 매핑 메타데이터를 조작할 수 있습니다.

hibernateProperties.put(EntityManagerFactoryBuilderImpl.INTEGRATOR_PROVIDER,
            (IntegratorProvider) () -> Collections.singletonList(JsonColumnMappingIntegrator.INSTANCE));

데모로서 Postgre만 체크하고 있습니다.SQL 및 나는 특정 엔티티의 특정 열에만 동적 columnDefinition을 적용합니다.

public class JsonColumnMappingIntegrator implements Integrator {

  public static final JsonColumnMappingIntegrator INSTANCE =
      new JsonColumnMappingIntegrator();

  @Override
  public void integrate(
      Metadata metadata,
      SessionFactoryImplementor sessionFactory,
      SessionFactoryServiceRegistry serviceRegistry) {

    Database database = metadata.getDatabase();

    if (PostgreSQL92Dialect.class.isAssignableFrom(database.getDialect().getClass())) {
      Column acolumn=
        ((Column) metadata.getEntityBinding(Atable.class.getName()).getProperty("acolumn").getColumnIterator().next());
      settingsCol.setSqlType("json");
    }
  }

  @Override
  public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
  }
}

metadata.getEntityBindings()모든 엔티티 바인딩을 제공합니다.이 바인딩을 통해 속성을 반복하고 반복할 수 있습니다.이것은 꽤 비효율적인 것 같습니다.또, 「IS JSON」의 제약 조건등을 설정할 수 있을지 어떨지 잘 모르기 때문에, 커스텀 작성 스크립트를 사용하는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/59703106/switch-from-jsonstringtype-to-jsonbinarytype-when-the-project-uses-both-mysql-an

반응형