Mapeando minha entidade

6 respostas
jpajava
D

possuo uma classe Cliente que será persisitido, minha duvida é a seguinte:
*nesta entidade terá um campo CPF onde será cadastrado que este CPF deste cliente com seus atributos para depois eu vou usar um autocomplete neste CPF que irá imprimir todos seus atributos cadastrado.

ai vem a pergunta, na minha entidade tem meu id, preciso substituir o para cpf? ou adiciono um atributo cpf?

6 Respostas

L

A resposta é: depende.

Se pro seu caso dá certo identificar um cliente pelo CPF, use-o como chave primária da sua tabela. Se não, usa um número mesmo e coloca o CPF em outro campo, muito provavelmente unique.

Já que você vai fazer pesquisas por CPF o tempo inteiro, caso ele não seja chave primária, vale a pena criar um index no banco de dados para agilizar a busca. Caso você esteja utilizando geração automática de tabelas, tem como fazer isso utilizando o atributo indexes da anotação @Table. Caso contrário, crie o índice manualmente no banco de dados.

D

hum… então no caso, eu coloco uma anotação @Table(indexex). Só que no caso eu tenho que passar [] seria o nome da indexes? então no caso melhor colocar outro campo e anoto @UniqueConstraint ?

Porque seria assim, vou cadastrar um cliente que se relaciona com um serviço, no dataTable irá mostrar as informações do serviço junto com cliente.

J

Utilizar CPF como chave primária não é uma boa prática e tão pouco recomendável. Você pode acompanhar alguns argumentos aqui.

D

blz obrigado! então vou criar um atributo CPF e deixar unique;

L

Não, pera. Para tudo.

Esquece o que eu falei sobre index por enquanto.

Você pode colocar o CPF como chave primária, colocando algo como:

@Id
private String cpf;

Certo? Se você não quer que seja chave primária, coloca algo como:

@Id
private long id;
private String cpf;

No caso que o CPF não é chave primária, você pode colocar uma constraint no CPF dizendo que ele deve ser único. Dessa forma, caso você tente inserir um CPF duplicado, vai acontecer um erro de validação no JPA Provider (hibernate, por exemplo). Para fazer isso, você faz assim:

@Id
private long id;
@Column(unique=true)
private String cpf;

Essa constraint é avaliada pelo JPA provider. Caso você queira que exista realmente uma constraint física no banco de dados, você deve fazer assim:

@Entity
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"cpf"})})
public class Usuario {...}

Onde cpf é o nome da coluna no DB. Essa constraint física vai ser criada se é o JPA Provider que está gerando suas tabelas.

Como o @jonas.cant falou, não é legal utilizar o CPF como chave primária mesmo. Eu recomendo a utilização de boas práticas independente da situação, mas se você tá fazendo um projetinho pra aprender ou algo do gênero, não se preocupe, vai cair tua mão se você profanar os dogmas da comunidade.

Entendendo o Index

Um index, no banco de dados, nada mais é do que um local onde é armazenado algumas colunas de uma tabela que você pode escolher. O index é uma cópia dessas colunas, e pode ter as vezes referências diretas às linhas correspondentes, ou até mesmo o endereço do bloco no disco onde aquele dado está armazenado fisicamente.

A vantagem principal de um index é a rapidez para se recuperar dados, quando o parâmetro de busca está em uma coluna que está no index.

Uma coluna que sempre está no index de uma tabela, por padrão, é sua chave primária! Por isso é tão mais rápido buscar pela chave primária.

Você pode adicionar quantas colunas você quiser ao index. No seu caso, por exemplo, você pode adicionar o cpf também, agilizando a busca.

Você provavelmente vai se perguntar: Então, porque não colocar a tabela inteira dentro do index? Não é mais rápido?

Resposta: Não! Manter o index é custoso. O banco de dados tem que lidar com dados duplicados, o que pode ser um problema de escalabilidade. Use com sabedoria!

Outra pergunta: como é que o banco de dados sabe que é pra usar o index na hora da busca, e não a coluna normal?

Resposta: Existe um mecanismo no DB chamado de Query Planner. Quando você manda uma query para o DB, ele não a executa logo de cara. Ele analisa tua query e tenta otimiza-la da melhor forma possível. Isso inclui utilizar o index, se for possível.

Agora sim, voltando para o teu caso.

Se você quiser que o JPA Provider construa os index no DB para você, pode utilizar o atributo que citei anteriormente, o indexes, na annotation @Table. Assim:

@Entity
@Table(indexes = {@Index(name = "i_cpf", columnList = "cpf"))})
public class Usuario {...}

Você pode colocar mais colunas se quiser, ali no columnList, dentro da mesma string, separando por vírgula, por exemplo: "cpf,nome,idade". Definindo esse atributo, o JPA Provider, na hora que estiver construindo teu banco de dados, vai criar um index chamado de acordo com o atributo name, e colocar nele as colunas dentro do atributo columnList. Mas como eu falei, não é o JPA que vai utilizar o index na hora da busca, e sim o query planner do banco de dados.

Sacou?

D

agora vai… rsrs obrigado aí!

Criado 8 de fevereiro de 2017
Ultima resposta 8 de fev. de 2017
Respostas 6
Participantes 3