如何为Spring数据中的类配置MongoDb集合名称

时间:2012-09-05 03:15:09

标签: java spring mongodb spring-data spring-data-mongodb

我的MongoDB数据库中有一个名为Products的集合,在我的Java代码中由接口IProductPrice表示。以下存储库声明使Spring Date查看集合db.collection: Intelliprice.iProductPrice

我希望它将其配置为使用外部配置查看db.collection: Intelliprice.Products,而不是在@Collection(..)上添加IProductPrice注释。这可能吗?我怎么能这样做?

public interface ProductsRepository extends
    MongoRepository<IProductPrice, String> {
}

5 个答案:

答案 0 :(得分:16)

目前唯一可以实现此目的的方法是使用@Document属性使用collection注释您的域类,以定义此类的集合实例的名称应保留为。

但是,有一个JIRA issue开放,建议添加一个可插入的命名策略来配置类,集合和属性名称以更全局的方式处理。请随意评论您的用例并进行投票。

答案 1 :(得分:10)

使用Oliver Gierke的回答, 在我需要为一个实体创建多个集合的项目上工作时,我想使用spring存储库,并且需要在使用存储库之前指定要使用的实体。

我设法使用此系统按需修改存储库集合名称,它使用SPeL。您一次只能处理1个集合。

域对象

@Document(collection = "#{personRepository.getCollectionName()}")
public class Person{}

默认Spring存储库:

public interface PersonRepository 
     extends MongoRepository<Person, String>, PersonRepositoryCustom{
}

自定义存储库接口:

public interface PersonRepositoryCustom {
    String getCollectionName();

    void setCollectionName(String collectionName);
}

实现:

public class PersonRepositoryImpl implements PersonRepositoryCustom {

    private static String collectionName = "Person";

    @Override
    public String getCollectionName() {
        return collectionName;
    }

    @Override
    public void setCollectionName(String collectionName) {
        this.collectionName = collectionName;
    }
}

使用它:

@Autowired
PersonRepository personRepository;

public void testRetrievePeopleFrom2SeparateCollectionsWithSpringRepo(){
        List<Person> people = new ArrayList<>();
        personRepository.setCollectionName("collectionA");
        people.addAll(personRepository.findAll());
        personDocumentRepository.setCollectionName("collectionB");
        people.addAll(personRepository.findAll());
        Assert.assertEquals(4, people.size());
}

否则,如果你需要使用配置变量,你可以使用这样的东西吗? source

@Value("#{systemProperties['pop3.port'] ?: 25}") 

答案 2 :(得分:1)

有点晚了, 但是我发现您可以在spring-boot中动态设置mongo集合名称,直接访问应用程序配置。

@Document(collection = "#{@environment.getProperty('configuration.property.key')}")
public class DomainModel {...}

我怀疑您可以通过这种方式设置任何注释属性。

答案 3 :(得分:0)

我唯一可以添加的评论是,您必须在bean名称上添加@前缀:

collection = "#{@beanName.method()}"

供bean工厂注入bean:

@Document(collection = "#{@configRepositoryCustom.getCollectionName()}")
public class Config {

}

我很难弄清楚。.

完整示例:

@Document(collection = "#{@configRepositoryCustom.getCollectionName()}")
public class Config implements Serializable {
 @Id
 private String uuid;
 private String profile;
 private String domain;
 private String label;
 private Map<String, Object> data;
 // get/set
}

 public interface ConfigRepositoryCustom {
   String getCollectionName();
   void setCollectionName(String collectionName);
 }

@Component("configRepositoryCustom")
public class ConfigRepositoryCustomImpl implements ConfigRepositoryCustom {
 private static String collectionName = "config";
 @Override
 public String getCollectionName() {
  return collectionName;
 }
 @Override
 public void setCollectionName(String collectionName) {
 this.collectionName = collectionName;
 }
}

@Repository("configurations")
public interface ConfigurationRepository extends MongoRepository<Config, String>, ConfigRepositoryCustom {
  public Optional<Config> findOneByUuid(String Uuid);
  public Optional<Config> findOneByProfileAndDomain(String profile, String domain);
}

serviceImpl中的用法:

@Service
public class ConfigrationServiceImpl implements ConfigrationService {
 @Autowired
 private ConfigRepositoryCustom configRepositoryCustom;

 @Override
 public Config create(Config configuration) {
   configRepositoryCustom.setCollectionName( configuration.getDomain() ); // set the collection name that comes in my example in class member 'domain'
   Config configDB = configurationRepository.save(configuration);
   return configDB;
}

答案 4 :(得分:0)

我在SpEL中使用静态类和方法;

public class CollectionNameHolder {
    private static final ThreadLocal<String> collectionNameThreadLocal = new ThreadLocal<>();

    public static String get(){
        String collectionName = collectionNameThreadLocal.get();
        if(collectionName == null){
            collectionName = DataCenterApiConstant.APP_WECHAT_DOCTOR_PATIENT_COLLECTION_NAME;
            collectionNameThreadLocal.set(collectionName);
        }
        return collectionName;
    }

    public static void set(String collectionName){
        collectionNameThreadLocal.set(collectionName);
    }

    public static void reset(){
        collectionNameThreadLocal.remove();
    }
}

在Entity类中,@ Document(collection =“#{T(com.test.data.CollectionNameHolder).get()}”)

然后,使用

CollectionNameHolder.set("testx_"+pageNum) 

服务,和

CollectionNameHolder.reset();

希望对您有帮助。