[RESOLVIDO] Dúvida sobre relacionamento n:n + Java

Olá, tenho uma tabela no banco mysql fazendo relação n:n para outras duas, uma relação de clientes de uma academia, e as séries que os clientes tem cadastradas…

A minha dúvida é o seguinte, eu sei como funciona o relacionamento no mysql, sendo que essa tabela ClientesTemSeries, vai recebe o id do cliente e o id de uma série, mas quando tenho o mesmo cliente com várias séries preciso de mais linhas…

ou seja

ClientesTemSeries_tbl    

IdCliente       |   IdSérie
    1           |   2
    1           |   3
    2           |   4
    2           |   2

Eu consigo tratar no java criando um objeto por linha, mas a minha intenção é criar um objeto por id de cliente… e que esse objeto receba as séries em uma lista…

a classe modelo em Java eu fiz asism:

    public class CustomerHasSeries {

    private Customer Customer;
    private List<Series> seriesList;

    //getters e setters

    }

Mas não estou conseguindo fazer dessa maneira, até então eu só consegui trabalhar um objeto por linha…

estou acessando o banco com a classe PreparedStatement

PreparedStatement stmt = null;
stmt = conn.prepareStatement(query.toString());
rs = stmt.executeQuery();

Alguma dica?

Agradeço desde ja a ajuda de todos!

Boa tarde @feebsilvaa,

por um acaso você já pensou em utilizar o Hibernate para fazer essa tarefa por você? Hibernate é uma ferramenta do tipo ORM (Object-relational mapping) que mapeia seu banco de dados às classes criadas no seu programa. Dê uma olhada no site que coloquei aí em cima, tem boas explicações sobre isso lá no site. Tem também esse tutorial da Caelum que mostra uma introdução ao JPA e o Hibernate.
Boa pesquisa! :slight_smile:

@feebsilvaa

Existem algumas formar para resolucao deste teu problema, colocarei uma que acho uma boa.

Imagine o seguinte, pelo menos na minha época, a cada 2 ou 3 meses o cliente recebia uma nova ficha contento uma nova lista de exercicios. Neste ponto, já é interessante termos uma data de controle, para saber quando aquela série foi criada logo, teremos algo assim

Caso fosse fazer um front-end para apresentar estes resultados, inicialmente apresentaria a lista de series que aquele aluno tem/teve ao longo da vida dele. Logo, faria a seguinte query.

QUERY 1 - TODOS OS ALUNO:

SELECT
	SCA.ID_ALUNO
	, AL.NOME_ALUNO
	, SCA.ID_SERIE
	, SCA.DT_CADASTRO
FROM 
	SERIE_COM_ALUNO SCA
INNER JOIN
	ALUNO AL
ON AL.ID_ALUNO = SCA.ID_ALUNO
GROUP BY 
	SCA.ID_ALUNO
	, AL.NOME_ALUNO
	, SCA.DT_CADASTRO
	, SCA.ID_SERIE
ORDER BY 
	SCA.ID_ALUNO,
	, SCA.ID_SERIE

RESULTADO QUERY 1:

QUERY 2 - APENAS ALUNO POR ID:

SELECT
	SCA.ID_ALUNO
	, AL.NOME_ALUNO
	, SCA.ID_SERIE
	, SCA.DT_CADASTRO
FROM 
	SERIE_COM_ALUNO SCA
INNER JOIN
	ALUNO AL
ON AL.ID_ALUNO = SCA.ID_ALUNO
WHERE SCA.ID_ALUNO = 1
GROUP BY 
	SCA.ID_ALUNO
	, AL.NOME_ALUNO
	, SCA.DT_CADASTRO
	, SCA.ID_SERIE
ORDER BY 
	SCA.ID_ALUNO,
	, SCA.ID_SERIE

texto em negrito

RESULTADO QUERY 2:

Segundo passo, seria listar os exercício envolvidos mediante serie selecionada.
Query para isto:

SELECT 
	ID_SERIE
	, NOME_EXERCICIO
	, QT_VEZES
	, QT_REPETICOES
FROM
	SERIE
INNER JOIN 
	APARELHO AP
ON
	AP.ID_APARELHO = SERIE.ID_APARELHO
WHERE
	ID_SERIE = 1

Resultado:

JAVA

Vamos para a parte legal, quando falamos de java (minha opniao e forma de trabalho) crio, na maioria das vezes, uma classe para cada tabela d meu banco de dados, com excessao das de relacionamento muitos para muitos.

Teremos entao as seguintes classes:

ALUNO
EXERCÍCIO
SERIE

Cada uma contendo como atributo as colunas da tabela.

exemplo:

Public class Aluno{
	private Long ID_ALUNO;
	private String NOME;
	private integer CPF;
	private Date DATA_CADASTRO;


	.. getters e setters vao aqui
	...
	....

}

Construiria também, classes para retorno destes resultados. Teria alguma coisa assim:

Public Class AlunoPorSerie{
	private Aluno aluno;
	private Serie serie;

	..getters e setters vao aqui
	....
	.....
}

Criaria uma Class DAOAluno e colocaria dentros desta a primeira query executada juntamente com o seu tratamento

public AlunoPorSerie getAlunoSerie(Long id_aluno){
	String query = " SELECT SCA.ID_ALUNO , AL.NOME_ALUNO , SCA.ID_SERIE , SCA.DT_CADASTRO FROM SERIE_COM_ALUNO SCA INNER JOIN ALUNO AL ON AL.ID_ALUNO = SCA.ID_ALUNO WHERE SCA.ID_ALUNO = ? GROUP BY SCA.ID_ALUNO , AL.NOME_ALUNO , SCA.DT_CADASTRO , SCA.ID_SERIE ORDER BY SCA.ID_ALUNO, , SCA.ID_SERIE" 
	PreparedStatement stmt = null;
	stmt = conn.prepareStatement(query.toString());
		... SET VALORES DO PREPARESTATEMENT
	rs = stmt.executeQuery();

	List<AlunoPorSerie> alunoList = new ArrayList<AlunoPorSerie> ();

	//tratamento do resultado
		WHILE rs.next(){
			//criacao dos objetos

			aluno = new Aluno();
			serie = new Serie();
			
			//setValores
			aluno.setNome (rs.getInteger(0));
				serie.setId(Integer.parseInt(getString("ID_ALUNO")));
				aluno.setNome (rs.getString("NOME_ALUNO"));
				serie.setIdSerie(Integer.parseInt(getString("ID_SERIE")));
			....DEMAIS VALORES AQUI!

			AlunoPorSerie alunoPorSerie = new AlunoPorSerie();
			
			//setando valores.
			alunoPorSerie.setAluno(aluno);
			alunoPorSerie.setSerie(serie);
			
			//inclusao novo objeto criado
			alunoList.add(AlunoPorSerie);
		}
	return alunoList;
}

Com o retorno desta método getAlunoSerie, fica fácil você montar e manipular o seu resultado em tela.

OBSERVAÇÕES IMPORTANTES

Esta forma de interação com o banco de dados e bem comum em projetos antigos. Como nosso saudoso amigo @felipe.machado disse, é bem mais fácil e menos custoso você utilizar um ORM. Se esta estudando por estudar com objetivo de crescimento profissional, indico o ORM (JPA com Hibernate). Se esta iniciando e isso e um trabalho de faculdade, e bem legal estudar esta forma que coloquei e acima, a mesma que está estudando. Lógico, que existem maneiras e maneiras de implementas a mesma coisa que coloquei aqui!

Espero poder ter ajudado e qualquer coisa posta aqui! Farei o meu melhor para ajuda-lo!

Atenciosamente,

Felipe Cabral.

Valeu pela dica mano, o único problema que eu teria nesse caso é que na fase que estou não poderia migrar toda a minha estrutura para Hibernate, ou seja não teria tempo hábil.

Mas, realmente é uma ótima ideia. Fiz um “mini” curso de JPA + Hibernate e achei legal.

Obrigado pelas dicas, me enjuriei final de semana passado e consegui resolver kkk e por coincidência segui esta lógica que você indicou antes mesmo de ter visto seu post, retornei o cliente varias vezes para uma lista, e obviamente como esta modelado do bd apesar se ser o mesmo cliente, cada objeto vinha com uma série diferente, aproveitei o fato do id ser igual e rodei um loop para reservar o primeiro id, e inserir a série dos demais ids no primeiro… e depois retornar um único objeto com todas as séries.

Obviamente que na classe modelo para Cliente eu mudei e ao invés de receber “private Serie serie”, passa a receber “private List seriesList”

basicamente foi isso…

e aproveitei a lógica e fiz o contrário também kk, peguei e criei uma regra para consultar por uma série e exibir todos os clientes que tem essa série relacionada…

matei 2 coelhos em uma só cajadada kkk

1 curtida

Parabéns!!!

Espero que este tópico possa ajudar mais pessoas no futuro!

Que bom que conseguiu. O desenvolvimento utilizando Hibernate é bem rápido (pelo menos para os casos padrão) e ainda mais rápido se utilizar uma IDE como a do Netbeans para gerar as classes automagicamente pra você.
Boa sorte no seu projeto