繁体   English   中英

Spring 启动Mongo数据-如何设置命名策略

[英]Spring Boot Mongo Data - How to Set Naming Strategy

亲爱的 Stack Overflow 社区,

我目前正在开发一个 Spring Boot 项目,其中变量名以驼峰式大小写形式编写。 我还有一个 MongoDB 数据库,其中的字段以蛇形大小写书写。 目前,我正在使用 Spring Mongo Data 提供的 @Field 注释到 map 每个变量及其相应的逻辑名称,如下所示:

@Field("var_name")
private String varName;

我的问题是 - 有没有办法在 Spring Mongo 数据中全局配置自动 Camel Case 到 Snake Case 转换? 如果我有一个带有许多实例变量的 model,那么为它们中的每一个添加一个 @Field 注释将是微不足道的。

先感谢您。

对于 Spring 启动,您可以将“field-naming-strategy”添加到您的 application.yml 中,如下所示:

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      username: xxxxx
      password: yyyyy
      authentication-database: admin
      database: my_mongo_db
      field-naming-strategy: org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy

您是否在 Mongo 配置 class 中尝试过 mappingContext.setFieldNamingStrategy(new SnakeCaseFieldNamingStrategy()) ?

有两种方法可以在全局级别执行此操作:

  1. 要覆盖 MongoMappingContext:
public class MongoConfig extends AbstractReactiveMongoConfiguration {

  @Override
  public MongoClient reactiveMongoClient() {
    return MongoClients.create(uri);
  }

  @Bean
  @Override
  public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions) throws ClassNotFoundException {
    MongoMappingContext mappingContext = new MongoMappingContext();
    mappingContext.setInitialEntitySet(this.getInitialEntitySet());
    mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
    mappingContext.setFieldNamingStrategy(new SnakeCaseFieldNamingStrategy()); //NOTE this line
    mappingContext.setAutoIndexCreation(this.autoIndexCreation());
    return mappingContext;
  }

这里我们重写 mappingContext 并传递 snakeCasing,默认为驼峰。

  1. 更新 codecRegistry
public MongoClient reactiveMongoClient() {
    return MongoClients.create(
        MongoClientSettings.builder().applyConnectionString(new ConnectionString(uri))
            .codecRegistry(codecRegistry())
            .build());
  }
  public CodecRegistry codecRegistry() {
    List<Convention> conventions = Collections.<Convention>singletonList(
        classModelBuilder -> {
          for (PropertyModelBuilder<?> fieldModelBuilder : classModelBuilder.getPropertyModelBuilders()) {
            fieldModelBuilder.discriminatorEnabled(false);
            fieldModelBuilder.readName(
                fieldModelBuilder.getName()
                    .replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
            fieldModelBuilder.writeName(
                fieldModelBuilder.getName()
                    .replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
          }

          classModelBuilder.enableDiscriminator(true);
          classModelBuilder.discriminatorKey("_cls");
          classModelBuilder.discriminator(classModelBuilder.getType().getSimpleName()
              .replaceAll("([^_A-Z])([A-Z])", "$1_$2").toLowerCase());
        });
    CodecProvider pojoCodecProvider =
        PojoCodecProvider.builder().conventions(conventions).build();
    return fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
  }

第二个取自此处提到的测试, 文档中有更好的解释
虽然我无法让第二个工作,但根据这个评论,它应该是理想的。

参考: https://github.com/mongodb/mongo-java-driver/blob/r3.5.0/bson/src/test/unit/org/bson/codecs/pojo/PojoCustomTest.java#L136

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM