

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Nivelar atributos de outras classes
<a name="ddb-en-client-adv-features-flatmap"></a>

Se os atributos da sua tabela estiverem espalhados por várias classes Java diferentes, seja por herança ou composição, a API do Cliente Aprimorado do DynamoDB fornece suporte para nivelar os atributos em uma classe.

## Usar herança
<a name="ddb-en-client-adv-features-flatmap-inheritance"></a>

Se suas classes usam herança, use as seguintes abordagens para nivelar a hierarquia.

### Usar beans anotados
<a name="ddb-en-client-adv-features-flatmap-inheritance-anno"></a>

Para a abordagem de anotação, ambas as classes devem conter a anotação `@DynamoDbBean` e uma classe deve conter uma ou mais anotações de chave primária.

Veja a seguir exemplos de classes de dados que têm uma relação de herança.

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer extends GenericRecord {
    private String name;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

@DynamoDbBean
public abstract class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

A [opção `onMethod`](https://projectlombok.org/features/experimental/onX) do Lombok copia anotações do DynamoDB baseadas em atributos, como `@DynamoDbPartitionKey`, no código gerado.

```
@DynamoDbBean
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord {
    private String name;
}

@Data
@DynamoDbBean
public abstract class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

### Usar esquemas estáticos
<a name="ddb-en-client-adv-features-flatmap-inheritance-static"></a>

Para a abordagem do esquema estático, use o método `extend()` do construtor para reduzir os atributos da classe principal para a classe secundária. Isso é mostrado depois da linha de comentário 1 no seguinte exemplo:

```
        StaticTableSchema<org.example.tests.model.inheritance.stat.GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.GenericRecord.class)
                        // The partition key will be inherited by the top level mapper.
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getId)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getCreatedDate)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<org.example.tests.model.inheritance.stat.Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.Customer.class)
                        .newItemSupplier(org.example.tests.model.inheritance.stat.Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(org.example.tests.model.inheritance.stat.Customer::getName)
                                .setter(org.example.tests.model.inheritance.stat.Customer::setName))
                        // 1. Use the extend() method to collapse the parent attributes onto the child class.
                        .extend(GENERIC_RECORD_SCHEMA)     // All the attributes of the GenericRecord schema are added to Customer.
                        .build();
```

O exemplo anterior do esquema estático usa as seguintes classes de dados: Uma vez que o mapeamento é definido quando você cria o esquema de tabela estática, as classes de dados não exigem anotações.

#### Classes de dados
<a name="gunk"></a>

------
#### [ Standard data class ]

```
public class Customer extends GenericRecord {
    private String name;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}


public abstract class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
```

------
#### [ Lombok ]

```
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord{
    private String name;
}

@Data
public abstract class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

## Usar composição
<a name="ddb-en-client-adv-features-flatmap-comp"></a>

Se suas classes usam composição, use as seguintes abordagens para nivelar a hierarquia.

### Usar beans anotados
<a name="ddb-en-client-adv-features-flatmap-comp-anno"></a>

A anotação `@DynamoDbFlatten` nivela a classe contida.

Os exemplos de classes de dados a seguir usam a anotação `@DynamoDbFlatten` para adicionar efetivamente todos os atributos da classe `GenericRecord` contida à classe `Customer`.

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer {
    private String name;
    private GenericRecord record;

    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    @DynamoDbFlatten
    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

@DynamoDbBean
public class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
@DynamoDbBean
public class Customer {
    private String name;
    @Getter(onMethod_=@DynamoDbFlatten)
    private GenericRecord record;
}

@Data
@DynamoDbBean
public class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

Você pode usar a anotação de nivelamento para nivelar quantas classes elegíveis forem necessárias. As limitações a seguir aplicam-se:
+ Todos os nomes de atributos devem ser exclusivos depois de serem nivelados.
+ Nunca deve haver mais de uma chave de partição, chave de classificação ou nome de tabela.

### Usar esquemas estáticos
<a name="ddb-en-client-adv-features-flatmap-comp-static"></a>

Ao criar um esquema de tabela estático, use o método `flatten()` do construtor. Você também fornece os métodos getter e setter que identificam a classe contida.

```
        StaticTableSchema<GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(GenericRecord.class)
                        .newItemSupplier(GenericRecord::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(GenericRecord::getId)
                                .setter(GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(GenericRecord::getCreatedDate)
                                .setter(GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getName)
                                .setter(Customer::setName))
                        // Because we are flattening a component object, we supply a getter and setter so the
                        // mapper knows how to access it.
                        .flatten(GENERIC_RECORD_SCHEMA, Customer::getRecord, Customer::setRecord)
                        .build();
```

O exemplo anterior do esquema estático usa as seguintes classes de dados:

#### Classes de dados
<a name="ddb-en-client-adv-features-flatmap-comp-static-supporting"></a>

------
#### [ Standard data class ]

```
public class Customer {
    private String name;
    private GenericRecord record;

    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

public class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
public class Customer {
    private String name;
    private GenericRecord record;
}

@Data
public class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

Você pode usar o padrão do construtor para nivelar quantas classes elegíveis forem necessárias.

## Implicações para outro código
<a name="ddb-en-client-adv-features-flatmap-compare"></a>

Quando você usa o atributo `@DynamoDbFlatten` (ou método `flatten()` do construtor), o item no DynamoDB contém um atributo para cada atributo do objeto composto. Isso também inclui os atributos do objeto de composição. 

Por outro lado, se você anotar uma classe de dados com uma classe composta e não usar `@DynamoDbFlatten`, o item será salvo com o objeto composto como um único atributo.

Por exemplo, compare a classe `Customer` mostrada no [exemplo de nivelamento com composição](#ddb-en-client-adv-features-flatmap-comp-anno) com e sem nivelamento do atributo `record`. Você pode visualizar a diferença com JSON conforme mostrado na tabela a seguir.


****  

| Com nivelamento | Sem nivelamento | 
| --- | --- | 
| 3 atributos | 2 atributos | 
|  <pre>{<br />  "id": "1",<br />  "createdDate": "today",<br />  "name": "my name"<br />}</pre>  |  <pre>{<br />  "id": "1",<br />  "record": {<br />      "createdDate": "today",<br />      "name": "my name"<br />  }<br />}</pre>  | 

A diferença se torna importante se você tiver outro código acessando a tabela do DynamoDB que espera encontrar certos atributos.