30

Products在我的 MongoDB 数据库中调用了一个集合,它由IProductPrice我的 Java 代码中的接口表示。以下存储库声明导致 Spring Date 查找集合db.collection: Intelliprice.iProductPrice

我希望它配置它以db.collection: Intelliprice.Products使用外部配置进行查看,而不是@Collection(..)IProductPrice. 这可能吗?我怎样才能做到这一点?

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

5 回答 5

24

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

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

于 2012-09-06T09:04:05.470 回答
20

使用上面 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());
}

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

@Value("#{systemProperties['pop3.port'] ?: 25}") 
于 2016-01-11T16:04:02.827 回答
7

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

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

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

于 2020-10-13T16:59:32.323 回答
3

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

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

让 bean factory 注入 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;
}
于 2019-02-16T17:30:28.200 回答
1

我在 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();
    }
}

在实体类中,@Document(collection = "#{T(com.test.data.CollectionNameHolder).get()}")

然后,使用

CollectionNameHolder.set("testx_"+pageNum) 

在服务中,和

CollectionNameHolder.reset();

希望它可以帮助你。

于 2020-03-26T12:05:30.017 回答