首页 > 解决方案 > 如何使用 mongodb 的 spring 数据存储库从具有动态字段名称的 mongo 存储库中获取数据?

问题描述

我正在使用 spring data JPA 从 mongoDB 获取数据。

public interface SupplierResponseRepo extends MongoRepository<SupplierResponse, String>  {}

@Document
public class SupplierResponse{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String supplierResponseId;
    private String orderId;
    private String orderName;
}

上面的代码在所有字段名称都固定之前一直有效,现在可以有多个字段并且它们的名称事先不知道,我希望获取所有字段。有什么方法可以做同样的事情,比如我可以将任何泛型类型传递给 MongoRepository 接口并获取所有列。

我对 mongoTemplate 有同样的问题,但后来使用 DBObject 解决了。

mongoTemplate.find(query, DBObject.class,"supplier");

MongoRepository 是否也有类似的替代方案?

标签: mongodbspring-bootspring-data-mongodb

解决方案


您可以使用自定义 Converter 类来使用 MongoRepository 获取数据。由于它是来自 Mongodb 的数据,因此您需要在 Spring Data 应用程序中进行映射,这@ReadingConverter是您需要的。

/**
 * @ReadingConverter: Spring data mongodb annotation to enable the class to handle the mapping of DBObject into Java
 * Objects
 */
@ReadingConverter
public class SupplierResponseConverter implements Converter<Document, SupplierResponse> {
    /**
     * Map DBObject to SupplierResponse inherited class according to the MongoDB document attributes
     * @param source MongoDB Document object
     * @return SupplierResponse Object
     */
    @Override
    public SupplierResponse convert(Document source) {
        if (source.get("supp_id") != null) {
            SupplierResponse supplierResponse = new SupplierResponse();
            supplierResponse.setSupplierId(source.get("supp_id", String.class)
        }
        //repeat this operation for all your attribute in order to map them according to a condition of your choice
}

然后,您需要在一个类中启用您的自定义转换器@Configuration类。你可以这样做。通过扩展,AbstractMongoConfiguration您将不得不覆盖其他一些方法。

/**
 * @Configuration: allow to register extra Spring beans in the context or import additional configuration classes
 */
@Configuration
public class DataportalApplicationConfig extends AbstractMongoConfiguration {

    //@Value: inject property values into components
    @Value("${spring.data.mongodb.uri}")
    private String uri;
    @Value("${spring.data.mongodb.database}")
    private String database;

    /**
     * Configure the MongoClient with the uri
     *
     * @return MongoClient.class
     */
    @Override
    public MongoClient mongoClient() {
        return new MongoClient(new MongoClientURI(uri));
    }

    /**
     * Database name getter
     *
     * @return the database the query will be performed
     */
    @Override
    protected String getDatabaseName() {
        return database;
    }

    /**
     * @Bean: explicitly declare that a method produces a Spring bean to be managed by the Spring container.
     * Configuration of the custom converter defined for the entity schema.
     * @return MongoCustomConversions.class
     */
    @Bean
    @Override
    public MongoCustomConversions customConversions() {
        List<Converter<?, ?>> converterList = new ArrayList<>();
        converterList.add(new ContactReadConverter());
        converterList.add(new GeometryGeoJSONReadConverter());
        converterList.add(new SamplingFeatureReadConverter());
        converterList.add(new SensorReadConverter());
        return new MongoCustomConversions(converterList);
    }

    /**
     * @Bean: explicitly declare that a method produces a Spring bean to be managed by the Spring container.
     * Configuration of the MongoTemplate with the newly defined custom converters. The MongoTemplate class is the
     * central class of Spring’s MongoDB support and provides a rich feature set for interacting with the database. The
     * template offers convenience operations to create, update, delete, and query MongoDB documents and provides a
     * mapping between your domain objects and MongoDB documents.
     *
     * @return MongoTemplate.class
     */
    @Bean
    @Override
    public MongoTemplate mongoTemplate() {
        MongoTemplate mongoTemplate = new MongoTemplate(mongoClient(), getDatabaseName());
        MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
        mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);
        mongoTemplate.setWriteConcern(WriteConcern.MAJORITY);
        mongoMapping.setCustomConversions(customConversions()); // tell mongodb to use the custom converters
        mongoMapping.afterPropertiesSet();
        return mongoTemplate;
    }
}

推荐阅读