[Resolvido] Insert em duas tabelas através de um único form

Boa tarde amigos, estou fazendo um trabalho pra a faculdade e to com um problema. No meu form de novo cliente eu tenho as informações do cliente e o endereço , porém são tabelas do mysql diferentes(relacionadas) e não sei como fazer o insert. Das outras vezes eu passava para o comando do sql aos parâmetros utilizando “?” como abaixo :

 private void adicionar() {
        String sql = "INSERT INTO usuario(nome,matricula,email,telefone,perfil,login,senha) VALUES (?,?,?,?,?,?,?)";
        try {
            //pega os dados do form e aplica o insert
            pst = conexao.prepareStatement(sql);
            pst.setString(1, txtUsuario.getText());
            pst.setString(2, txtMatricula.getText());
            pst.setString(3, txtEmail.getText());
            pst.setString(4, txtFone.getText());
            pst.setString(5, comboboxPerfil.getSelectedItem().toString());
            pst.setString(6, txtLogin.getText());
            pst.setString(7, password.getText());
//Validação dos campos obrigatórios
            if ((txtMatricula.getText().isEmpty()) || (txtUsuario.getText().isEmpty()) || (txtLogin.getText().isEmpty()) || (password.getText().isEmpty())
                    || (comboboxPerfil.getSelectedIndex() == 0)) {
                JOptionPane.showMessageDialog(null, "Preencha todos os campos obrigatórios", "Aviso!", JOptionPane.INFORMATION_MESSAGE);

            } else {

                //executa a query
                int adicionado = pst.executeUpdate();
                if (adicionado > 0) {
                    JOptionPane.showMessageDialog(null, "Usuário salvo com sucesso", "Aviso!", JOptionPane.INFORMATION_MESSAGE);
                    txtUsuario.setText(null);
                    txtEmail.setText(null);
                    txtFone.setText(null);
                    comboboxPerfil.setSelectedItem(null);
                    txtLogin.setText(null);
                    password.setText(null);
                    txtMatricula.setText(null);
                }
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        }

    } 

Só que agora eu teria que fazer um insert em duas tabelas, oq eu deveria fazer? Criar uma outra varivel tipo String e passar outra instrução sql? to perdido.

obrigado desde ja!

primeiro, por que vc precisa inserir em duas tabelas?

segundo, se o ultimo insert falhar, o que vc espera que aconteça com os dados do primeiro?

geralmente um insert duplo esta encadeado, entao vc precisa abrir uma TRANSACTION e fazer COMMIT ou ROLLBACK ao final.

Então, um professor meu me disse uma vez no 3 período que endereço no geral é sempre adequado criar uma tabela só para ele e ter “rua” “numero” “bairro” e etc como atributos ao invés de endereço ser um atributo único para cliente por exemplo. Ai eu criei a tabela de clientes , a de endereço e relacionei as duas. Só que no form é tudo uma coisa só.

Não sei como funciona mas pensei que ele só executaria o insert se os dois fossem funcionar, algo como um if com operador lógico && . até porque quando o cliente X for cadastrado ele terá o endereço X pois o endereço terá a pk do cliente como fk.

Nesse caso eu teria que utilizar mesmo o TRANSACTION?

Desculpe se falei alguma besteira é meu primeiro vez desenvolvendo um sistema.

Ola

se o seu cliente so pode ter um endereço, isso é discutivel.

E vc pode dividir o cadastro em varias etapas: na primeira vc pede nome e depois vc pede endereço e dependendo do negocio o camarada pode ter varios ( imagine endereço para receber uma entrega q vc pode colocar a casa dos pais, dos avós, trabalho, etc). se o endereço for obrigatorio vc pode mostrar uma mensagem “magrão, completa teu cadastro senão vai tomar tapa na orelha”.

Tipo, vc gosta de preencher longos cadastros? Pense nisso, pode ser outra solução

de qq forma vc precisa aprender sobre transações

http://dev.mysql.com/doc/refman/5.7/en/commit.html

basicamente vc inicia uma transação no banco e começa a inserir. ao final vc pode dar um commit e ai tudo sera persistido, ou fazer rollback que nada sera salvo.

transações podem ser custosas ao banco de dados. pense nisso no futuro quando vc tiver milhares de acessos por dia.

1 curtida

Muito obrigado! passei o dia nisso mas consegui fazer funcionar assim :

    private void adicionarPainelInfos() {
        String sql = "INSERT INTO cliente (nome,email,cnpj,cpf,telefone) VALUES (?,?,?,?,?)";
        String sql2 = "INSERT INTO endereco (rua,numero,cidade,complemento,cep,bairro,uf) VALUES (?,?,?,?,?,?,?)";
        

        try {
            conexao.setAutoCommit(false);
//pega os dados do form e aplica o insert
            pst = conexao.prepareStatement(sql);
            pst.setString(1, txtNome.getText());
            pst.setString(2, txtEmail.getText());
            pst.setString(3, txtCnpj.getText());
            pst.setString(4, txtCpf.getText());
            pst.setString(5, txtTelefone.getText());

//Validação dos campos obrigatórios
            if ((txtNome.getText().isEmpty()) || (txtTelefone.getText().isEmpty()) || (txtEmail.getText().isEmpty()) || (txtLogradouro.getText().isEmpty()) || (txtNumero.getText().isEmpty()) || (txtCidade.getText().isEmpty()) || (txtComplemento.getText().isEmpty()) || (txtCep.getText().isEmpty()) || (txtBairro.getText().isEmpty()) || (comboboxUf.getSelectedIndex() == 0)) {
                JOptionPane.showMessageDialog(null, "Preencha todos os campos obrigatórios", "Aviso!", JOptionPane.INFORMATION_MESSAGE);
            } else {
                Savepoint ponto1 = conexao.setSavepoint();
//executa a query
                int adicionado = pst.executeUpdate();

                //entra no try para os egundo insert
                if (adicionado > 0) {
                    try {
                        pst = conexao.prepareStatement(sql2);
                        pst.setString(1, txtLogradouro.getText());
                        pst.setString(2, txtNumero.getText());
                        pst.setString(3, txtCidade.getText());
                        pst.setString(4, txtComplemento.getText());
                        pst.setString(5, txtCep.getText());
                        pst.setString(6, txtBairro.getText());
                        pst.setString(7, comboboxUf.getSelectedItem().toString());

                        int adicionado2 = pst.executeUpdate();
                        if (adicionado2 > 0) {

                            txtNome.setText(null);
                            txtEmail.setText(null);
                            txtCnpj.setText(null);
                            txtCpf.setText(null);
                            txtTelefone.setText(null);

                            txtLogradouro.setText(null);
                            txtNumero.setText(null);
                            txtCidade.setText(null);
                            txtComplemento.setText(null);
                            txtCep.setText(null);
                            txtBairro.setText(null);
                            comboboxUf.setSelectedIndex(0);

                        }

                    } catch (Exception e) {
                        JOptionPane.showMessageDialog(null, e);
                        conexao.rollback(ponto1);//retorna ao save point e desfaz o 1st insert
                    }
                }
            }

            conexao.commit();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        }
    }

Ai quando pensei que finalmente meus problemas tinham acabado percebi uma coisa… Não to cadastrando a pk do Cliente no campo Fk de endereco . pesquisei varias coisas e estou eu empacado de novo , poderiam me dar uma luz?
Por enquanto estou ainda com a ideia de estar tudo no mesmo form mas caso eu faça o cadastro em etapas, teria o mesmo problema de passar a pk…

abs