web-dev-qa-db-ja.com

Spring DataのクラスのMongoDbコレクション名を構成する方法

MongoDBデータベースにProductsというコレクションがあります。これは、JavaコードのインターフェースIProductPriceで表されます。次のリポジトリ宣言により、Spring Dateはコレクション_db.collection: Intelliprice.iProductPrice_を見てください。

IProductPrice@Collection(..)アノテーションを付けるのではなく、外部構成を使用して_db.collection: Intelliprice.Products_を検索するように構成する必要があります。これは可能ですか?これどうやってするの?

_public interface ProductsRepository extends
    MongoRepository<IProductPrice, String> {
}
_
26
Danish

現在これを実現できる唯一の方法は、collectionプロパティを使用してドメインクラスに@Documentで注釈を付け、永続化するこのクラスのコレクションインスタンスの名前を定義することです。

ただし、プラグイン可能な名前付け戦略を追加して、クラス、コレクション、プロパティ名をよりグローバルな方法で処理する方法を構成することを提案する JIRAの問題 オープンがあります。ユースケースにコメントして自由に投票してください。

18
Oliver Drotbohm

上記のOliver Gierkeの回答を使用して、1つのエンティティに対して複数のコレクションを作成する必要があるプロジェクトで作業し、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}") 
12
Jeremie

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();

お役に立てば幸いです。

0
leimbag

追加できる唯一のコメントは、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;
}
0
ylev