1. Mapeamento de associação unidirecional individual
O modelo de objeto de relacionamento um para muitos é frequentemente visto na vida cotidiana. Tome os alunos e as aulas como exemplo. Existem vários alunos em uma turma, portanto, o relacionamento entre a turma e os alunos é um relacionamento de um para muitos, mapeado para o modelo de objeto, como mostrado na figura abaixo:
O modelo de objeto mostra que esse relacionamento um para muitos é mantido por uma extremidade, portanto o mapeamento para um modelo de relacionamento significa que haverá vários alunos em um campo de classe, que forma um relacionamento de um para muitos. As informações do aluno podem ser obtidas através da turma. O modelo de relacionamento correspondente é o seguinte:
1. Configuração básica
Com o modelo de objeto, mapeie -os no código de relacionamento correspondente. Ao executar o mapeamento de relacionamento, você precisa adicionar a tag <ene-to-Many> em uma extremidade. Além disso, você precisa adicionar o atributo definido em uma extremidade. Ele suporta carregamento preguiçoso e, em seguida, adicione a etiqueta definida no arquivo de mapeamento e especifique um relacionamento um para muitos, para que você possa consultar e obter a extremidade múltipla em uma extremidade.
Aulas e arquivos de mapeamento:
É o fim mais importante do modelo. Nesse final, você precisa adicionar o atributo SET correspondente e adicionar a tag Definir no arquivo de configuração. Você pode configurar o objeto correspondente <ene-to-Many> na tag Definir. O código do objeto de classes.java é o seguinte:
pacote com.src.hibernate; importar java.util.set; classe pública Classes {private int id; public int getId () {return id; } public void setId (int id) {this.id = id; } public string getName () {return name; } public void setName (nome da string) {this.name = name; } nome de string privado; // o conjunto suporta carregamento preguiçoso de alunos privados; public set getStudents () {return Students; } public void SetStudents (Set Students) {this.students = alunos; }}O atributo SET é usado no objeto Classes, mas explica apenas os atributos de carregamento atrasado e não configura o objeto correspondente para o atributo. O objeto do atributo precisa ser configurado no arquivo de mapeamento. Você precisa adicionar uma tag definida e adicionar a tag <ne-to-many> à tag definida. O código específico é o seguinte:
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeamento dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.ddddd"> <hiberMate-Mapping.Net/BERNATEM-MAPAPD) tabela = "t_classes"> <id name = "id"> <generator // id> <propriedade name = "name"/> <set name = "estudantes"> <key column = "classesid"> </key> <one-to-many> </one-to-many> </set> </slt> </hibernate>
O código e os arquivos de mapeamento no objeto do aluno correspondente não requerem nenhuma configuração especial, eles precisam ser gravados de acordo com o método usual de escrita. O método de configuração específico não será descrito em detalhes, é muito simples. Após a configuração, você precisa gerar a instrução SQL correspondente. Ao converter o modelo de objeto em um modelo relacional, o hibernato gera a instrução correspondente da seguinte forma:
alter table t_student drop foreign key FK4B9075705E0AFEFE drop table if exists t_classes drop table if exists t_student create table t_classes (id integer not null auto_increment, name varchar(255), primary key (id)) create table t_student (id integer not null auto_increment, name varchar(255), classesid Inteiro, chave primária (id)) ALTER TABELA T_STUDENT ADD INDEX FK4B9075705E0AFEFE (CLASSESID), Adicione restrições FK4B9075705E0AFEFE Chave estranha (ClassesID) Referências T_Classes (ID)
O modelo de relacionamento correspondente gerado é mostrado abaixo:
Comparando declarações SQL e modelos de relacionamento, a associação entre tabelas correspondentes é mantida através de chaves estrangeiras. Primeiro, crie duas tabelas, especifique a chave primária da tabela e, finalmente, adicione um relacionamento de associação de chave estrangeira individual.
2. Operações básicas
As operações no banco de dados nada mais são do que ler e escrever, e a modificação também é um tipo de gravação. Em seguida, vamos ver como escrever e ler operações no banco de dados.
(1) Escreva dados:
Ao escrever dados, você precisa prestar atenção ao relacionamento um para muitos, para que você precise adicionar várias aulas de alunos ao adicioná-las. Além disso, como o atributo set correspondente é adicionado às classes, você deve usar o hashset para adicionar ao adicionar objetos do aluno, para que você possa realizar um relacionamento um para muitos. O código específico é o seguinte:
public void testSave2 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); Aluno aluno1 = novo aluno (); Student1.setName ("Zhangsan"); session.Save (Student1); Aluno aluno2 = novo aluno (); Student2.SetName ("Lisi"); session.Save (Student2); Classes classes = novas classes (); classes.setName ("clássico"); Definir alunos = new hashset (); alunos.add (Student1); alunos.add (Student2); classes.setstudents (estudantes); // Os dados podem ser salvos com sucesso //, mas uma declaração de atualização extra será emitida para manter o relacionamento porque é um dos motivos de um para muitos.Save (classes); session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }} Então, depois que os dados correspondentes gerados executando o caso de teste acima são gravados no banco de dados, a figura a seguir é a seguinte:
(2) Leia os dados:
A operação de gravação é relativamente simples. Você só precisa adicionar todos os objetos carregados ao estado transitório e executar o método correspondente para inserir o conteúdo. No entanto, a operação de leitura correspondente será um pouco mais complicada. Como é necessário iterar para obter todos os objetos dos alunos, esse relacionamento de um para muitos não é muito eficiente. O código específico é o seguinte:
pacote com.test.hibernate; importar java.util.iterator; importar java.util.set; importação com.src.hibernate.*; import junit.framework.testcase; importar org.hibernate.session; public class One2Manytest estende o teste {public void testLoad1 () {session session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // Obtenha informações de classe com a chave primária 5 classes aulas = (classes) session.load (classes.class, 5); // Print Class Information System.out.println ("classes.name ="+classes.getName ()); // Defina o conjunto do aluno e carregue o aluno definido através da turma definindo alunos = aulas.getStudents (); // itera o conjunto e imprima as informações do aluno no conjunto para (iterator iter = student.iterator (); iter.hasnext ();) {Student student = (student) iter.next (); System.out.println ("student.name ="+student.getName ()); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}}As declarações e informações correspondentes geradas são as seguintes:
Hibernate: selecione Classes0_.id como id1_0_, classes0_.name como name1_0_ de t_classes Classes0_ onde classes0_.id =? classes.name = classone hibernate: selecione estudantes0_.classeSid como classid1_, estudantes0_.id como id1_, estudantes0_.id como id0_0_, estudantes0_.name como name0_0_ de t_student students0_ where Students0_.classesid =? student.name = lisi student.name = zhangsan
2. Mapeamento de associação bidirecional individual
Aqui continuamos a usar estudantes e aulas como exemplos. Há um relacionamento um para muitos entre a turma e os alunos. Existem vários alunos em uma turma. Ao contrário do artigo anterior, o relacionamento aqui é de mão dupla, ou seja, uma extremidade e uma extremidade mantêm o relacionamento ao mesmo tempo, então seu diagrama de objetos é o seguinte:
O diagrama do modelo de relacionamento correspondente não muda muito, porque a relação entre eles é bidirecional; portanto, ambos os fins do modelo de relacionamento mantêm o relacionamento ao mesmo tempo e o mapeiam para o modelo de relacionamento, como mostrado na figura abaixo:
Em uma associação única, o arquivo de mapeamento só precisa ser configurado especialmente em uma extremidade. Use a configuração <ene-to-Many> e use o iterador SET no modelo de objeto para definir o modelo de objeto sobrecarregado. No entanto, a diferença é que, em uma associação bidirecional, a associação de chave estrangeira correspondente na outra extremidade precisa ser adicionada na extremidade múltipla. Neste momento, o relacionamento de <fast-to-one> deve ser usado na extremidade múltipla para indicar essa bidirecionalidade.
1. Mapeamento
Aulas e estudantes também são usados como exemplos aqui. O conteúdo nas classes termina é o mesmo que acima e não muda, mas a configuração dos alunos nas múltiplas extremidades mudará, ou seja, a tag <fast-to-one> precisa ser adicionada ao arquivo de mapeamento.
A configuração do arquivo de mapeamento do Student.hbm.xml requer a adição de uma coluna de chave estrangeira <Many-to-One>, e o nome da coluna deve ser consistente com o nome da coluna de chaves estrangeiras de classes.hbm.xml. O código específico é o seguinte:
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate tabela = "t_student"> <id name = "id"> <generator/generator/> </id> <propriedade name = "name"/> <!-Adicione uma coluna de novas classes no aluno de um lado, e o nome da coluna deve ser o mesmo que a classes de classes. </hibernate-mapping>
A configuração do arquivo de mapeamento de classes.hbm.xml é o mesmo do artigo anterior. Deve -se notar que o mapeamento de atributos definido é adicionado ao arquivo classes.java e corresponde ao objeto do aluno. Portanto, a tag definida precisa ser adicionada ao arquivo de mapeamento para indicar que o iterador definido é usado no modelo de objeto. A configuração específica é a seguinte:
<? xml versão = "1.0"?> <! Doctype Hibernate-mapping público "-// Hibernate/hibernate mapeamento dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate tabela = "t_classes"> <id name = "id"> <generator // id> <propriedade name = "name"/> <set name = "estudantes" inverse = "true"> <key column = "classesid"> </key> </hib-spains>
2. Classe
A configuração do arquivo de mapeamento é correspondente diretamente à classe; portanto, com o arquivo de mapeamento, você pode gravar a classe correspondente. Com a mesma classe, você pode saber como escrever o arquivo de mapeamento correspondente. Vamos dar uma olhada em como escrever o código de classe correspondente.
A aula do Student.java exige a adição de atributos de objeto de classe associados à classe e você pode obter informações relacionadas às aulas ao carregar o aluno.
pacote com.src.hibernate; Classe de classe pública {// Classe de classe Associated Classes Private Classes; Classes públicas getClasses () {return Classes; } public void setClasses (classes classes) {this.classes = classes; } // ID do aluno privado int id; public int getId () {return id; } public void setId (int id) {this.id = id; } // Nome do aluno Nome da sequência privada; public String getName () {Return Name; } public void setName (nome da string) {this.name = name; }} O conteúdo específico do código das classes.java é mostrado no artigo anterior e não será descrito em detalhes aqui.
Com o modelo de objeto, o modelo de relacionamento é gerado. A instrução SQL gerada é a seguinte:
alter table t_student drop foreign key FK4B907570FC588BF4 drop table if exists t_classes drop table if exists t_student create table t_classes (id integer not null auto_increment, name varchar(255), primary key (id)) create table t_student (id integer not null auto_increment, name varchar(255), classesid Inteiro, chave primária (ID)) ALTER TABELA T_STUDENT ADD INDEX FK4B907570FC588BF4 (CLASSESID), Adicione restrições FK4B907570FC588BF4 Chave estrangeira (Classid) referências t_classes (ID)
3. Operação de dados
Depois de estabelecer uma estrutura de tabela, escrevi um método de teste para verificar a operação de dados. Primeiro, vamos dar uma olhada na inserção de dados e inserir dados na estrutura da tabela. Existem duas situações ao escrever dados. Primeiro é criar um objeto de classes, escrever o objeto no banco de dados, depois criar um objeto de aluno e adicionar o objeto do aluno ao objeto de aulas; O outro é primeiro criar um objeto de estudante, escrever o objeto do aluno no banco de dados e, em seguida, criar um objeto de aulas para adicionar o objeto do aluno ao objeto de aulas. Esses dois tipos de operações são diferentes no final, então vamos comparar.
3.1 Escreva primeiro a turma e depois escreva os alunos
Depois de escrever a classe no banco de dados primeiro, o objeto de classes entra no estado transitório e possui uma linha no banco de dados. Em seguida, escreva o objeto do aluno. O objeto do aluno procurará a chave primária das classes correspondentes e a escreverá na tabela. Portanto, os dados no modelo de relacionamento não estão vazios e o código salvo é o seguinte:
public void testSave () {sessão session = null; tente {// Criar sessão do objeto sessão = hibernateUtils.getSession (); // Abra a transação session.BegIntransaction (); // Crie objeto de classe de classe e escreva o objeto das classes de banco de dados = novas classes (); classes.setName ("classe"); session.Save (classes); // Crie o objeto do aluno 1 e escreva o objeto do aluno no banco de dados do aluno1 = new Student (); Student1.setName ("Zhangsan"); Student1.setClasses (aulas); session.Save (Student1); // Crie objeto do aluno 2 e escreva o objeto do aluno para o banco de dados Student2 = new Student (); Student2.SetName ("Lisi"); estudante2.setClasses (aulas); session.Save (Student2); session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }} A lista de informações correspondente no banco de dados de gravação é a seguinte:
3.2 Escreva os alunos primeiro e depois a aula
Primeiro, escreva os alunos no banco de dados. No momento, como a tabela do aluno precisa obter as informações principais da coluna de classe correspondente, mas como as informações da classe são convertidas no estado transitório, haverá um valor nulo ao escrever as informações do aluno. O código é o seguinte:
A visualização do banco de dados correspondente após a escrita é a seguinte:
Comparando as duas operações de gravação, resultados diferentes aparecem porque a ordem das duas gravações é diferente, mas por ser uma associação bidirecional, nenhuma exceção ocorre durante a escrita.
4. Operação de leitura
Comparado com os dados de gravação, os dados de leitura se tornam muito simples. Por ser uma associação bidirecional, a leitura de dados também é bidirecional. As informações da outra extremidade podem ser lidas de qualquer extremidade, conforme mostrado no código a seguir:
public void testLoad1 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // Leia as informações do aluno através das aulas de aula de aulas = (Classes) session.load (classes.class, 1); System.out.println ("classes.name ="+classes.getName ()); Set alunos = classes.getStudents (); for (iterator iter = student.iterator (); iter.hasnext ();) {Student student = (aluno) iter.next (); System.out.println ("student.name ="+student.getName ()); } // Leia as informações da aula através de informações do aluno Student Stu = New Student (); STU = (Student) session.load (Student.class, 1); System.out.println ("Carregar informações da classe através das classes do aluno.id ="+stu.getclasses (). GetId ()); session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}Execute a declaração de teste acima e as informações correspondentes de declaração geradas são as seguintes:
Hibernate: selecione Classes0_.id como id1_0_, classes0_.name como name1_0_ de t_classes Classes0_ onde classes0_.id =? Classes.name = Classe Hibernate: Selecione estudantes0_.classeSid como ClassID1_, estudantes0_.id como id1_, estudantes0_.id como id0_0_, estudantes0_.name como name0_0_, estudantes0_.classesid como classid0_0_ de t_student estudantes0_ student.name = lisi student.name = zhangsan
Carregando as informações da aula das aulas dos alunos.id = 1