如何使用 spring 数据存储库为 mongodb 从 mongo 存储库中获取具有动态字段名称的数据?
How to use spring data repository for mongodb to fetch data from mongo repositories with dynamic field names?
我正在使用 spring 数据 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 是否也有类似的替代方案?
您可以使用自定义转换器 class 通过 MongoRepository 获取数据。由于它是来自 Mongodb 的数据,您需要在 Spring 数据应用程序中映射,这是您需要的 @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
class 中启用自定义转换器 class。你可以这样做。通过扩展 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;
}
}
我正在使用 spring 数据 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 是否也有类似的替代方案?
您可以使用自定义转换器 class 通过 MongoRepository 获取数据。由于它是来自 Mongodb 的数据,您需要在 Spring 数据应用程序中映射,这是您需要的 @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
class 中启用自定义转换器 class。你可以这样做。通过扩展 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;
}
}