如何在使用 @DynamoDbTable 注解时动态传递 AWS DynamoDB 表名。

huangapple go评论67阅读模式
英文:

How to pass aws dynamodb table name dynamically using @DynamoDbTable annotation

问题

我已经创建了一个用于从DynamoDB获取详细信息的Java服务,它正常运行,但我的挑战是我在类文件中为**@DynamoDbTable**注解硬编码了表名称,以便在不同环境中使用。我觉得这不是正确的方式。我在下面提供了我的代码,有人可以帮助我解决这个问题。

代码示例

public class DynamodbService {

	private DynamoDB client;
	private DynamoDBMapper objectMapper;

	/**
	 * 
	 * @param client
	 * @param objectMapper
	 */
	@Autowired
	public DynamodbService(DynamoDB client, DynamoDBMapper objectMapper) {
		this.client = client;
		this.objectMapper = objectMapper;
	}

	public List<Dynamodb> findAll() throws Exception {
		DynamoDBMapperConfig mapperConfig = new DynamoDBMapperConfig.Builder()
				.withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(""))
				.build();
		DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);

		DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();

		List<Dynamodb> scanResult = objectMapper.scan(Dynamodb.class, scanExpression);
		return scanResult;
	}

}

我的DynamoDB配置

@Configuration
public class DynamoDBconfig {
	/**
	 * 
	 */
	@Value("${amazon.dynamodb.accesskey}")
	private String awsAccessKey;
	/**
	 * 
	 */
	@Value("${amazon.dynamodb.secretkey}")
	private String awsSecretKey;

	@Bean
	public AWSCredentials amazonAWSCredentials() {
		return new BasicAWSCredentials(aes.getDecryptedvalue(awsAccessKey), aes.getDecryptedvalue(awsSecretKey));
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	public DynamoDBMapperConfig dynamoDBMapperConfig() {
		return DynamoDBMapperConfig.DEFAULT;
	}

	/**
	 * 
	 * @param amazonDynamoDB
	 * @param config
	 * @return
	 */
	@Bean
	public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
		return new DynamoDBMapper(amazonDynamoDB, config);
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	public AmazonDynamoDB amazonDynamoDB() {
		return AmazonDynamoDBClientBuilder.standard().withCredentials(amazonAWSCredentialsProvider())
				.withRegion(Regions.US_EAST_2).build();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	public DynamoDB dynamoDB() {
		return new DynamoDB(amazonDynamoDB());
	}

	/**
	 * 
	 * @return
	 */
	public AWSCredentialsProvider amazonAWSCredentialsProvider() {
		return new AWSStaticCredentialsProvider(amazonAWSCredentials());
	}

}

我DynamoDB服务中的错误

> 构造函数DynamoDBMapper(DynamoDB,DynamoDBMapperConfig)未定义

我无法找出问题所在。如果我在类文件中使用表名称,它正常工作,但如果我尝试使用代码替换表名称,就会出现错误。

英文:

I have created a java service to get the details from dynamodb it is working fine but my challenge is i hardcoded the table name to the class file @DynamoDbTable annotation in order to work with different environments i feel it is not the right way. I have given my code below could someone help me to resolve the issue.

Code sample

public class DynamodbService {
private DynamoDB client;
private DynamoDBMapper objectMapper;
/**
* 
* @param client
* @param objectMapper
*/
@Autowired
public DynamodbService(DynamoDB client, DynamoDBMapper objectMapper) {
this.client = client;
this.objectMapper = objectMapper;
}
public List&lt;Dynamodb&gt; findAll() throws Exception {
DynamoDBMapperConfig mapperConfig = new DynamoDBMapperConfig.Builder()
.withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(&quot;&quot;))
.build();
DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig);
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
List&lt;Dynamodb&gt; scanResult = objectMapper.scan(Dynamodb.class, scanExpression);
return scanResult;
}
}

My DynamoDB config

@Configuration
public class DynamoDBconfig {
/**
* 
*/
@Value(&quot;${amazon.dynamodb.accesskey}&quot;)
private String awsAccessKey;
/**
* 
*/
@Value(&quot;${amazon.dynamodb.secretkey}&quot;)
private String awsSecretKey;
@Bean
public AWSCredentials amazonAWSCredentials() {
return new BasicAWSCredentials(aes.getDecryptedvalue(awsAccessKey), aes.getDecryptedvalue(awsSecretKey));
}
/**
* 
* @return
*/
@Bean
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return DynamoDBMapperConfig.DEFAULT;
}
/**
* 
* @param amazonDynamoDB
* @param config
* @return
*/
@Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB, DynamoDBMapperConfig config) {
return new DynamoDBMapper(amazonDynamoDB, config);
}
/**
* 
* @return
*/
@Bean
public AmazonDynamoDB amazonDynamoDB() {
return AmazonDynamoDBClientBuilder.standard().withCredentials(amazonAWSCredentialsProvider())
.withRegion(Regions.US_EAST_2).build();
}
/**
* 
* @return
*/
@Bean
public DynamoDB dynamoDB() {
return new DynamoDB(amazonDynamoDB());
}
/**
* 
* @return
*/
public AWSCredentialsProvider amazonAWSCredentialsProvider() {
return new AWSStaticCredentialsProvider(amazonAWSCredentials());
}
}

ERROR in my dynamodb service

> The constructor DynamoDBMapper(DynamoDB, DynamoDBMapperConfig) is undefined

I am unable find out what is the issue. If i use table name in class file it's working fine if i try to replace the table name using code it ends up with error.

答案1

得分: 5

DynamoDBMapper期望使用AmazonDynamoDB的任何实现,而不是DynamoDB类。

public DynamoDBMapper(
            final AmazonDynamoDB dynamoDB,
            final DynamoDBMapperConfig config) {

您只需要在服务中注入DynamoDBMapper。

@Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB) {
  DynamoDBMapperConfig config = new DynamoDBMapperConfig.Builder().withTableNameOverride(TableNameOverride.withTableNameReplacement(tableName))
        .build();
   return new DynamoDBMapper(amazonDynamoDB, config);
}

另一个选项是使用com.amazonaws.services.dynamodbv2.document.DynamoDB类,但在那里您不能使用DynamoDBScanExpression,您需要重写您的代码。

String desiredTabledName = "table-name";
Table table = dynamoDB.getTable(desiredTabledName);

您有多个选项

 - table.scan()和table查询
 - Index index = table.getIndex(indexName);
   index.scan()或index.query()
 - 您可以将`QuerySpec``ScanSpec`传递给上述所有选项
英文:

DynamoDBMapper expects any implementation of AmazonDynamoDB but not DynamoDB class.

public DynamoDBMapper(
            final AmazonDynamoDB dynamoDB,
            final DynamoDBMapperConfig config) {

You need to inject only the DynamoDBMapper in your service.

@Bean
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB) {
  DynamoDBMapperConfig config = new DynamoDBMapperConfig.Builder().withTableNameOverride(TableNameOverride.withTableNameReplacement(tableName))
        .build();
   return new DynamoDBMapper(amazonDynamoDB, config);
}

Other option could be using com.amazonaws.services.dynamodbv2.document.DynamoDB class but there you could not use DynamoDBScanExpression and you need to rewrite your code.


String desiredTabledName = &quot;table-name&quot;;
Table table = dynamoDB.getTable(desiredTabledName);


You have multiple options.

 - table.scan() and table query.
 - Index index = table.getIndex(indexName);
   index.scan() or index.query()
 - You could pass `QuerySpec` and `ScanSpec` to all above.  

huangapple
  • 本文由 发表于 2020年8月18日 01:25:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63455756.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定