Como devo gravar os dados de uma maneira mais funcional no banco?

Olá pessoal, boa tarde.

Estou fazendo um sistema desktop para cadastros de clientes em JAVA, sendo eles pessoa física ou jurídica, minha regra de negócio diz que, um cliente pode ter um ou vários contatos, segue exemplo da modelagem:

EmpresaContatos

Agora a dúvida é, durante o processo de cadastro, eu não tenho ainda uma Cod para virar uma chave estrangeria na tabela contato, então segue a forma que executo esse processo.

1º - Eu chamo o método ADD, da minha classe EmpresaDao, ele é um booleano.

2ª - Eu verifique o método dentro de um if, se ele retornar true, ele entra no if, eu recupero o código da última empresa cadastrada, e começo o processo para cadastrar os contatos referentes a ela, exemplo:

if(dao.add(obj))
{
        ContatoDao daoC = new ContatoDao();
        for(Contato c: Contatos)
        {
           c.setFkEmpresa(dao.ultimoCod())
           daoC.add(c);
        }
}

basicamente assim, a dúvida é, existe uma maneira melhor de fazer isso? Já ouvi falar sobre, commit rollback, mas, não sei ao certo como utilizar, desde já, agradeço a disposição de vocês!

Basicamente a ideia é trabalhar com transações, ter dados consistentes, ou seja, se algo der errado no meio da transação, você desfaz tudo usando rollback, caso contrário, se ocorrer tudo perfeitamente você confirma a transação aplicando commit.

Pense no processo todo como a realização de vários cadastros em ordem e sequência única, ou seja, isso se aplica sempre que e existirem registros dependentes como é o seu caso.

Muito obrigado pela explicação, por favor, como eu nunca utilizei essas transações, você teria algum exemplo, para que eu possa criar da melhor maneira?

Está desenvolvendo com JDBC puro ou está usando algum framework de persistência de dados?

Estou utilizando JDBC, fazendo os metodos e etc…

Tranquilo, então dá uma olhada nessa vídeo aula aqui abaixo, a didática é bem tranquila, acredito que já deve resolver pra você!

Se ainda assim permanecer alguma dúvida ou qualquer coisa, volte aqui no fórum, poste a sua dúvida com detalhes e o que tentou fazer que vamos te ajudando!

Salve, assisti os videos, na minha cabeça era necessário a criação de uma função no banco de dados e chamar por ela, mas, fiz as modificações aqui, e parece que deu certo, vou tentar melhorar, só fiquei meio inconformado por precisar usar uma função para recuperar o Id do banco de dados para criar a chave estrangeira na tabela contatos, mas, valeu a pena esse conhecimento, meu método para gravar empresa e seus contatos ficou assim.

public boolean add(Empresa obj, ArrayList<Contato> contatos){
    
    PreparedStatement pstm = null;
    Connection con = ConnectionBank.getConnetion();
    
    String sql = "INSERT INTO empresa (FkLogradouro, RazaoSocial, NomeFantasia, CNPJ, IE, IM, NumLocal, DataHora, Excluido) VALUES (?, ?, ?, ?, ?, ?, ?, Now(), ?);";
    String sql1 = "INSERT INTO Contato (FkPessoa, FkEmpresa, TipoContato, Descricao, DataHora, Excluido) VALUES (?, ?, ?, ?, Now(), ?);";
    
    try 
    {
        con.setAutoCommit(false);
        
        pstm = con.prepareStatement(sql);
        
        pstm.setInt(1, obj.getFkLogradouro());
        pstm.setString(2, obj.getRazaoSocial());
        pstm.setString(3, obj.getNomeFantasia());
        pstm.setString(4, obj.getCNPJ());
        pstm.setString(5, obj.getIE());
        pstm.setString(6, obj.getIM());
        pstm.setString(7, obj.getNumLocal());
        pstm.setString(8, obj.getExcluido());
        pstm.execute();
        
        pstm = con.prepareStatement(sql1);
        
        //Define Id da empresa como chave estrangeira para contatos
        int FkEmpresa = retornaProximoId();
        for(int i=0; i<contatos.size(); i++) {
            
            contatos.get(i).setFkEmpresa(FkEmpresa);

            pstm.setInt(1, 0);
            pstm.setInt(2, contatos.get(i).getFkEmpresa());
            pstm.setString(3, contatos.get(i).getTipoContato());
            pstm.setString(4, contatos.get(i).getDescricao());
            pstm.setString(5, contatos.get(i).getExcluido());

            pstm.execute();
        }
        
        con.commit();
        
        return true;
    }
    catch (SQLException ex)
    {
        JOptionPane.showMessageDialog(null, "OCORREU UM ERRO DURANTE O PROCESSO: Class EmpresaDao public boolean add(Empresa obj)."+ex, "Erro", JOptionPane.ERROR_MESSAGE);
        try 
        {
            con.rollback();
        }
        catch (SQLException ex1)
        {
            Logger.getLogger(EmpresaDao.class.getName()).log(Level.SEVERE, null, ex1);
        }
    }
    finally
    {
        ConnectionBank.closeConnection(con, pstm);
    }    
    
    return false;
}

Qualquer modificação que vocês acharem necessária, eu estarei realizando, obrigado!

Complementando o que o @Jonathan_Medeiros disse, reforço, aprenda e utilize transaçoes, é sempre importante e fundamental quando está manipulando várias tabelas ao mesmo tempo.

Para resolver seu problema de saber o ID antes, buscar o último código cadastrado, nao é uma boa idéia. Imagine que o sistema está lento, duas pessoas estao cadastrando empresas ao mesmo tempo).

Há algumas boas práticas pra resolver isso:

  • Se a chave primária está sendo gerada no banco, a api do JDBC já fornece métodos para retornar o id gerado. Procure por “jdbc generated keys” (Nao me lembro o nome do método)

  • Gerar a chave primária no cliente, ao invés do banco. Esse é o método que prefiro ultimamente, mas pode ser mais complexo de implementar, entao sugiro usar a primeira opçao.

1 curtida

Obrigado pela dica, vou verificar esse método, e tentar deixar de uma maneira mais profissional.