我正在使用AWS ECS托管我的应用程序,并使用DynamoDB进行所有数据库操作。因此,对于不同的环境,我将拥有具有不同表名的相同数据库。例如“ dev_users”(用于Dev env),“ test_users”(用于Test env)等。(这就是我们公司在不同环境中使用同一Dynamo帐户的方式)
因此,我想使用通过“ AWS ECS任务定义”环境参数传递的环境变量来更改模型类的“ tableName”。
例如。
我的模型课程是:
@DynamoDBTable(tableName = "dev_users")
public class User {
现在,当我在测试环境中部署容器时,需要用“ test”替换“ dev”。我知道我可以使用
@Value("${DOCKER_ENV:dev}")
访问环境变量。但是我不确定如何在类外使用变量。有什么方法可以使用docker env变量选择表前缀吗?
我的意图是这样使用:
我知道不可能这样。但是还有其他方法或解决方法吗?
编辑1:
我正在研究拉胡尔的答案,并面临一些问题。在写问题之前,我将解释我遵循的过程。
过程:
检查图像是否有错误:
我没有更改用户模型类中的任何内容,因为在执行bean时bean将替换DynamoDBTable的名称。但是表名超过骑马正在发生。数据仅从“模型类”级别给出的表名称中提取。
我在这里想念什么?
答案 0 :(得分:2)
可以通过更改的DynamoDBMapperConfig bean更改表名称。
对于必须为每个表加上文字前缀的情况,可以这样添加Bean。这里的前缀可以是您所用环境的名称。
@Bean
public TableNameOverride tableNameOverrider() {
String prefix = ... // Use @Value to inject values via Spring or use any logic to define the table prefix
return TableNameOverride.withTableNamePrefix(prefix);
}
有关更多详细信息,请在此处查看完整的详细信息: https://github.com/derjust/spring-data-dynamodb/wiki/Alter-table-name-during-runtime
答案 1 :(得分:1)
我对其他答案投了赞成票,但这是一个主意:
使用所有用户详细信息创建基类:
@MappedSuperclass
public abstract class AbstractUser {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
创建2个具有不同表名和spirng配置文件的命令:
@Profile(value= {"dev","default"})
@Entity(name = "dev_user")
public class DevUser extends AbstractUser {
}
@Profile(value= {"prod"})
@Entity(name = "prod_user")
public class ProdUser extends AbstractUser {
}
创建一个使用映射的超类的单个JPA存储库
public interface UserRepository extends CrudRepository<AbstractUser, Long> {
}
然后切换弹簧轮廓的弹性
@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
@Transactional
public class UserRepositoryTest {
@Autowired
protected DataSource dataSource;
@BeforeClass
public static void setUp() {
System.setProperty("spring.profiles.active", "prod");
}
@Test
public void test1() throws Exception {
DatabaseMetaData metaData = dataSource.getConnection().getMetaData();
ResultSet tables = metaData.getTables(null, null, "PROD_USER", new String[] { "TABLE" });
tables.next();
assertEquals("PROD_USER", tables.getString("TABLE_NAME"));
}
}
答案 2 :(得分:1)
关于在运行时更改表名的需求,我们有同样的问题。我们正在使用Spring-data-dynamodb 5.0.2,以下配置似乎提供了我们所需的解决方案。
首先,我注释了我的bean访问器
@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "getDynamoDBMapperConfig", basePackages = "my.company.base.package")
我还设置了一个名为ENV_PREFIX的环境变量,该变量是通过SpEL通过Spring连接的。
@Value("#{systemProperties['ENV_PREFIX']}")
private String envPrefix;
然后我设置一个TableNameOverride bean:
@Bean
public DynamoDBMapperConfig.TableNameOverride getTableNameOverride() {
return DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(envPrefix);
}
最后,我使用TableNameOverride注入设置了DynamoDBMapperConfig bean。在5.0.2中,我们必须在DynamoDBMapperConfig构建器中设置标准的DynamoDBTypeConverterFactory以避免NPE。
@Bean
public DynamoDBMapperConfig getDynamoDBMapperConfig(DynamoDBMapperConfig.TableNameOverride tableNameOverride) {
DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
builder.setTableNameOverride(tableNameOverride);
builder.setTypeConverterFactory(DynamoDBTypeConverterFactory.standard());
return builder.build();
}
事后看来,我可以设置一个DynamoDBTypeConverterFactory bean,该bean返回一个标准DynamoDBTypeConverterFactory,并使用DynamoDBMapperConfig构建器将其注入到getDynamoDBMapperConfig()方法中。但这也可以做。
答案 3 :(得分:0)
我能够获得以活动配置文件名称为前缀的表名称。
首先添加了TableNameResolver类,如下所示,
private void ControlRotateModel()
{
try
{
((model)elementHost.Child).rotate3D();
}
catch (Exception ex)
{
//
}
}
然后按如下所示设置DynamoDBMapper bean,
@Component
public class TableNameResolver extends DynamoDBMapperConfig.DefaultTableNameResolver {
private String envProfile;
public TableNameResolver() {}
public TableNameResolver(String envProfile) {
this.envProfile=envProfile;
}
@Override
public String getTableName(Class<?> clazz, DynamoDBMapperConfig config) {
String stageName = envProfile.concat("_");
String rawTableName = super.getTableName(clazz, config);
return stageName.concat(rawTableName);
}
}
添加了变量envProfile,这是一个可从application.properties文件访问的活动配置文件属性值。
@Bean
@Primary
public DynamoDBMapper dynamoDBMapper(AmazonDynamoDB amazonDynamoDB) {
DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDB,new DynamoDBMapperConfig.Builder().withTableNameResolver(new TableNameResolver(envProfile)).build());
return mapper;
}