是否可以在 spring 启动时连接到两个不同的 couchbase 桶
Is it possible to connect to two different buckets of couchbase in spring boot
我正在尝试使用 spring 引导连接到 couchbase 中的两个不同存储桶。但是在单个 spring 引导应用程序中,数据库配置仅采用单个存储桶名称。
是否可以在 spring-boot 中连接到多个 couchbase 桶?
您可能想说的是 Spring boot 提供了您可以修改的预定义属性,例如:couchbase.cluster.bucket
采用单个值并且您想连接到两个或更多的水桶。
如果您找不到更好的解决方案,我可以为您指出一种稍微不同的方法,即设置您自己的 couchbase 连接管理器,您可以将其注入到您需要的任何地方。
这里是 @Service
的示例,它将为您提供到不同存储桶的两个连接。
您可以根据自己的需要进行修改,它非常小。
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
@Service
public class CouchbaseConnectionManager {
private static final int TIMEOUT = 100000;
@Value("#{configProp['couchbase.nodes']}")
private List<String> nodes = new ArrayList<String>();
@Value("#{configProp['couchbase.binary.bucketname']}")
private String binaryBucketName;
@Value("#{configProp['couchbase.nonbinary.bucketname']}")
private String nonbinaryBucketName;
@Value("#{configProp['couchbase.password']}")
private String password;
private Bucket binaryBucket;
private Bucket nonbinaryBucket;
private Cluster cluster;
private static final Logger log = Logger.getLogger(CouchbaseConnectionManager.class);
@PostConstruct
public void createSession() {
if (nodes != null && nodes.size() != 0) {
try {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().connectTimeout(TIMEOUT).build();
cluster = CouchbaseCluster.create(env, nodes);
binaryBucket = cluster.openBucket(binaryBucketName, password);
nonbinaryBucket = cluster.openBucket(nonbinaryBucketName, password);
log.info(GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS + binaryBucket + " " + nonbinaryBucket);
} catch (Exception e) {
log.warn(UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS);
}
} else {
log.warn(COUCH_NOT_CONFIGURED);
}
}
@PreDestroy
public void preDestroy() {
if (cluster != null) {
cluster.disconnect();
log.info(SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE);
}
}
public Bucket getBinaryBucket() {
return binaryBucket;
}
public Bucket getNonbinaryBucket() {
return nonbinaryBucket;
}
private static final String SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE = "Successfully disconnected from couchbase";
private static final String GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS = "Got a connection to couchbase buckets: ";
private static final String COUCH_NOT_CONFIGURED = "COUCH not configured!!";
private static final String UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS = "Unable to get connection to couchbase buckets";
}
所以您似乎想在 Spring 启动应用程序中使用 Spring Data Couchbase,并且(至少)有两个不同的存储库由两个不同的 Bucket
支持?
您必须以编程方式自定义 Spring 数据配置(而不是让 Spring Boot 完成所有繁重的工作),但这是可能的。
- Spring 引导创建一个
CouchbaseConfigurer
,通过它创建默认 Cluster
和 Bucket
(在属性文件中调整)。
- 如果您的 class 路径上有
CouchbaseRepository
,它还会尝试通过实例化 SpringBootCouchbaseDataConfiguration
class 来配置 Spring 数据。
- 您可以通过在您的项目中扩展上面的
SpringBootCouchbaseDataConfiguration
来自定义它,将其标记为 @Configuration
准备好以编程方式自定义 Spring 数据配置后,您需要创建第二个 Bucket
bean,第二个 CouchbaseTemplate
使用该存储桶,以及然后指示 Spring Data Couchbase 在哪个模板上使用哪个 Repository
.
为此,有一个 configureRepositoryOperationsMapping(...)
方法。您可以使用此方法的参数作为构建器来:
- link 到
CouchbaseTemplate
的特定 Repository
接口:map
- 说任何具有特定实体类型的回购都应该使用给定的模板:
mapEntity
- 甚至重新定义要使用的默认模板(最初由 Spring Boot 创建的模板):
setDefault
.
第二部分在 Spring Data Couchbase documentation 中解释。
我遵循 Simon 的方法,将 org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration
扩展为 @Configuration
而不是 SpringBootCouchbaseDataConfiguration
。
此外,值得一提的一点是,出于某种原因,拥有单独的 Repository
包并拥有自己的 @Configuration
并不真正有效。我努力尝试让它工作并最终决定将所有存储库放在一个包中并最终得到类似下面的东西来映射 Entities
和 Templates
.
baseMapping.mapEntity(Prime.class, noSQLSearchDBTemplate())
.mapEntity(PrimeDetailsMaster.class, noSQLSearchDBTemplate())
.mapEntity(HostDetailsMaster.class, noSQLSearchDBTemplate())
.mapEntity(Events.class, eventsTemplate())
.mapEntity(EventRulesMaster.class, eventsTemplate());
我正在尝试使用 spring 引导连接到 couchbase 中的两个不同存储桶。但是在单个 spring 引导应用程序中,数据库配置仅采用单个存储桶名称。
是否可以在 spring-boot 中连接到多个 couchbase 桶?
您可能想说的是 Spring boot 提供了您可以修改的预定义属性,例如:couchbase.cluster.bucket
采用单个值并且您想连接到两个或更多的水桶。
如果您找不到更好的解决方案,我可以为您指出一种稍微不同的方法,即设置您自己的 couchbase 连接管理器,您可以将其注入到您需要的任何地方。
这里是 @Service
的示例,它将为您提供到不同存储桶的两个连接。
您可以根据自己的需要进行修改,它非常小。
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
@Service
public class CouchbaseConnectionManager {
private static final int TIMEOUT = 100000;
@Value("#{configProp['couchbase.nodes']}")
private List<String> nodes = new ArrayList<String>();
@Value("#{configProp['couchbase.binary.bucketname']}")
private String binaryBucketName;
@Value("#{configProp['couchbase.nonbinary.bucketname']}")
private String nonbinaryBucketName;
@Value("#{configProp['couchbase.password']}")
private String password;
private Bucket binaryBucket;
private Bucket nonbinaryBucket;
private Cluster cluster;
private static final Logger log = Logger.getLogger(CouchbaseConnectionManager.class);
@PostConstruct
public void createSession() {
if (nodes != null && nodes.size() != 0) {
try {
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().connectTimeout(TIMEOUT).build();
cluster = CouchbaseCluster.create(env, nodes);
binaryBucket = cluster.openBucket(binaryBucketName, password);
nonbinaryBucket = cluster.openBucket(nonbinaryBucketName, password);
log.info(GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS + binaryBucket + " " + nonbinaryBucket);
} catch (Exception e) {
log.warn(UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS);
}
} else {
log.warn(COUCH_NOT_CONFIGURED);
}
}
@PreDestroy
public void preDestroy() {
if (cluster != null) {
cluster.disconnect();
log.info(SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE);
}
}
public Bucket getBinaryBucket() {
return binaryBucket;
}
public Bucket getNonbinaryBucket() {
return nonbinaryBucket;
}
private static final String SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE = "Successfully disconnected from couchbase";
private static final String GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS = "Got a connection to couchbase buckets: ";
private static final String COUCH_NOT_CONFIGURED = "COUCH not configured!!";
private static final String UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS = "Unable to get connection to couchbase buckets";
}
所以您似乎想在 Spring 启动应用程序中使用 Spring Data Couchbase,并且(至少)有两个不同的存储库由两个不同的 Bucket
支持?
您必须以编程方式自定义 Spring 数据配置(而不是让 Spring Boot 完成所有繁重的工作),但这是可能的。
- Spring 引导创建一个
CouchbaseConfigurer
,通过它创建默认Cluster
和Bucket
(在属性文件中调整)。 - 如果您的 class 路径上有
CouchbaseRepository
,它还会尝试通过实例化SpringBootCouchbaseDataConfiguration
class 来配置 Spring 数据。 - 您可以通过在您的项目中扩展上面的
SpringBootCouchbaseDataConfiguration
来自定义它,将其标记为@Configuration
准备好以编程方式自定义 Spring 数据配置后,您需要创建第二个 Bucket
bean,第二个 CouchbaseTemplate
使用该存储桶,以及然后指示 Spring Data Couchbase 在哪个模板上使用哪个 Repository
.
为此,有一个 configureRepositoryOperationsMapping(...)
方法。您可以使用此方法的参数作为构建器来:
- link 到
CouchbaseTemplate
的特定Repository
接口:map
- 说任何具有特定实体类型的回购都应该使用给定的模板:
mapEntity
- 甚至重新定义要使用的默认模板(最初由 Spring Boot 创建的模板):
setDefault
.
第二部分在 Spring Data Couchbase documentation 中解释。
我遵循 Simon 的方法,将 org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration
扩展为 @Configuration
而不是 SpringBootCouchbaseDataConfiguration
。
此外,值得一提的一点是,出于某种原因,拥有单独的 Repository
包并拥有自己的 @Configuration
并不真正有效。我努力尝试让它工作并最终决定将所有存储库放在一个包中并最终得到类似下面的东西来映射 Entities
和 Templates
.
baseMapping.mapEntity(Prime.class, noSQLSearchDBTemplate())
.mapEntity(PrimeDetailsMaster.class, noSQLSearchDBTemplate())
.mapEntity(HostDetailsMaster.class, noSQLSearchDBTemplate())
.mapEntity(Events.class, eventsTemplate())
.mapEntity(EventRulesMaster.class, eventsTemplate());