[Resolvido] Utilizando Herança em Java com Banco de dados

Pessoal, bom dia.

Em minha aplicação desktop tenho algumas Jframes que possuem informações iguais, exemplo: Clientes e funcionários: nome, cpf, rg, data de nascimento, email, etc. No banco eu tenho duas tabelas com as mesmas informações, foi quando me falaram sobre Herança:

Agora me surgiu uma dúvida: Como trabalhar com a inserção no banco de dados? Estou utilizando um Dao para fazer essa inserção, como vou utilizar uma sql para registrar pessoa, cliente e funcionário?

Não se complique com essas soluções academicas. São entidades com responsabilidades diferentes, podendo inclusive estar ou evoluir para módulos independentes.

Ou seja é melhor deixar do jeito que está e esquecer o conceito de Herança?

Fala Márcio,

    Você pode criar classes com métodos de acesso genérico ao banco de dados. Seria mais ou menos isso sua dúvida?? Seria o que se chama de Reflection, não?
1 curtida

Olá Marcio ! sobre como inserir nas tabelas, não é difícil a partir do ponto em que você entende como
funciona o conceito de herança. o que pode facilitar a inclusão no seu banco, é realmente como você modela as classes, um exemplo , Pessoa, Clientes e funcionários, um cliente pode ser também um funcionário, e um funcionário pode ter as mesmas características de um cliente, como nome,rg,cpf,endereço entre outras, herança neste caso é onde Clientes e funcionário, herdam as propriedades de Pessoa, já que toda pessoa tem um nome, cpf,rg etc. o que pode ser feito para seu sistema ficar mais coerente, diminuir as dependências de classes, acoplamento etc, é separar as tabelas, um grosso exemplo, Pessoa, Cliente, Endereco, Contato, ou Cliente, Endereco, Contato,
todo cliente tem um endereço, e todo cliente tem um contato ( telefone,email etc) a inserção no banco, já entra outra
questão que é relacionamento das tabelas, uma questão que vai precisar aprender
para modelar seu banco de dados, isso vai vir com estudos, agora, tem um longo caminho pela frente, aprenda primeiro como inserir, excluir, alterar dados em seu banco, modelar suas classes, herança, o conceito de herança, pois até isso tem que se tomar cuidado, ai , depois parta para a parte visual, que no meu ponto de vista é o mais chato.

1 curtida

O ideal é que você tivesse uma tabela PESSOA e que CLIENTE e FUNCIONARIO tivessem apenas uma chave estrangeira para essa tabela PESSOA. Daí no seu modelo de objetos você poderia usar composição para relacionar as duas classes. Porém, se as suas tabelas já estiverem prontas, alimentadas com dados e em produção, eu diria que não vale a pena você fazer esse refactoring.

PS: misturar herança e ORM só vai complicar a sua vida, sem nenhum ganho significativo.

1 curtida

Então, acredito que sim. Mais a duvida é como usar o conceito tendo em vista a herança das classes.

Entendi, acho que vou deixar em tabelas separadas pois está tudo funcional, e vou tentar aplicar nas minhas próximas aplicações.

Marcelo, sua dica foi boa sobre a questão de usar chave estrangeira, nas próximas aplicações vou modelar melhor o banco de dados.

te passo um exemplo se tiver disposto a ver como realmente pode ser feito !

faz isso por favor?

Eu acho que já está bem explicado, mas vou tentar ajudar também,

Primeiramente, sendo uma classe bem genérica, não faria mais sentido Pessoa ser abstrata? Ou você realmente precisa de entidades mais genéricas em seu programa? (Porque se for trabalhar só com Cliente e Funcionário (e suas heranças) ter objetos muito genéricos não ajudaria muito, acredito eu).

Enfim…
Digamos que você tem uma classe mais genérica Pessoa (com atributos String nome, int CPF, etc). Dessa classe herdam as mais específicas Cliente e Funcionário (com seus respectivos campos e métodos especificos).

Começando pelo banco :

Você pode criar a tabela Pessoa, que guarda as informações genéricas.Ou seja, ela tem colunas :

int ID_Pessoa (PK, identity, not null);
varchar(max) Nome_Pessoa (not null);
etc…

E também tem as tabelas Cliente e Funcionário, que guardam as informações específicas dessas respectivas entidades.

Para fazer a ligação entre as tabelas, você pode adicionar em Cliente e Funcionário a coluna ID_Pessoa, e adicionar uma FK esta coluna referenciando ID_Pessoa da tabela Pessoa. Assim, ao consultar dados de um Funcionário, por exemplo, você pode puxar junto, pela FK, os dados genéricos dele guardados em Pessoa.

Você ainda pode adicionar um campo na tabela Pessoa como "Entidade", por exemplo, que guarda um texto informado o que aquele registro é (se é Cliente ou Funcionário).

No programa, você pode ter uma PessoaDAO, que terá, por exemplo, o método inserirPessoa(Pessoa p). Esse método insere um objeto Pessoa no banco de dados, sendo ele uma Pessoa genérica, um Cliente ou um Funcionário.

Crie então ClienteDAO e FuncionarioDAO. Nelas, crie o métodos inserirCliente(Pessoa p)e insrirFuncionario(Pessoa p), respectivamente.

Nesses dois métodos supracitados, você pode chamar o método inserirPessoa(Pessoa p), para inserir genericamente (ou seja, inserir aqueles dados como CPF, etc). Depois você usa um ResultSet para recuperar o ID da Pessoa que você inseriu e, logo após, você insere na tabela Cliente / Funcionario os dados específicos, usando o ID que você recuperou.

Pode ainda usar métodos estáticos para recuperar o ID_Pessoa, se precisar em um outro contexto, mas não sei se é uma boa prática.

Enfim, acho que é isso…

2 curtidas

E se uma Pessoa for Cliente e Funcionario ao mesmo tempo ? Percebe que a herança não suporta essa situação ?

1 curtida

de uma olhada neste repositório do github, tem exatamente o que você precisa,
a persistência das Classes clientes, endereço, contato separado por camadas e cada
entidade em sua tabela. obs: o framework utilizado é JDBC. é bem simples e de fácil compreendimento. de uma olhada no código, se não conseguir entender me fala.

https://github.com/ercarval/coc-odonto-swing

1 curtida

me desculpe, mas não entendi seu raciocínio !

O problema é que ao usar herança para fazer esse modelo você viola o princípio da identidade de um objeto, veja:

class Pessoa{
    String cpf;
    String nome;
}

class Funcionario extends Pessoa{
    String numeroMatricula;
    BigDecimal salario;
}

class Cliente extends Pessoa{
    String codigo;
    List<Compra> historicoCompras;
}

joaoCliente = new Cliente();
joaoCliente.cpf = "12345678900";
joaoCliente.nome = "Joao das Neves"

joaoFuncionario = new Funcionario()
joaoFuncionario.cpf = "12345678900";
joaoCliente.nome = "Joao das Neves"

//resultado -> 2 objetos representando a mesma pessoa, a mesma entidade

perceba que você tem 2 objetos no mesmo contexto representando a mesma entidade. Isso viola um dos princípios da OO que diz que um objeto tem identidade, ou seja, um objeto deve ser uma representação única da entidade que ele representa. Nesse caso, a herança está introduzindo uma duplicação ao invés de eliminá-la. Um design mais correto seria:

class Pessoa{
    String cpf, nome;
};

class  Funcionario{
    String matricula;
    BigDecimal salario;
    Pessoa pessoa;
}

class Cliente{
  String codigo;
  List<Compra> historico;
  Pessoa pessoa;
 }
 
 joao = new Pessoa();
 joao.cpf = "12345678900"
 joao.nome = "Joao das Neves"

 funcionario = new Funcionario();
 funcionario.pessoa = joao;

 cliente = new Cliente()
 cliente.pessoa = joao;
3 curtidas

ah sim… exatamente por estes motivos também, como mencionei em minha
resposta: modelar suas classes, herança, o conceito de herança, pois até isso tem que se tomar cuidado . deve se entender o conceito de herança e a exata aplicação, pra quem esta iniciando os
estudos em OO é fundamental.
uma outra questão também é a real necessidade da classe e a responsabilidade dela, Pessoa em si pode ter todos os atributos que um Cliente tem, ou vice-versa. pode ser que nem seja necessário existir a Classe Pessoa, já que cliente teria a mesma responsabilidade

1 curtida