1. Associação Primária Bidirecional
Associação-chave primária bidirecional é na verdade um caso especial de associação principal primária individual. No entanto, a configuração <ene-to-one> deve ser realizada nos arquivos de mapeamento nas duas extremidades do objeto associado e, além disso, o atributo de associação estrangeira de chave estrangeira deve ser usada em uma extremidade da chave primária do mapa principal.
Aqui também usamos a pessoa e o IDCARD para discutir. Uma pessoa corresponde a um cartão de identificação exclusivo, e um cartão de identificação também mapeia de maneira única uma pessoa, então isso cria um relacionamento de associação de mão dupla. A chave principal da pessoa também é a chave primária do IDCARD, que são chaves primárias e chaves estrangeiras. Esse relacionamento de associação se torna um mapeamento individual de duas vias, que pode ser expresso no modelo de relacionamento, como mostrado abaixo:
As duas tabelas da figura usam associação principal primária. A chave primária da pessoa é a chave primária do IDCARD; portanto, eles formam uma relação restrição entre as chaves estrangeiras de Zhu e garantem a singularidade, mapeiam-a no modelo de objeto e a transformam em um relacionamento individual entre a classe de pessoa e a classe Idcard, como mostrado na figura abaixo:
Esse relacionamento individual também mencionou no artigo anterior que a tag <ene-to-one> é usada, e esse mapeamento individual é bidirecional, por isso precisamos configurar <neone-one> entre dois objetos ao mesmo tempo. Primeiro, vejamos o código da classe e o código de arquivo de mapeamento correspondente ao IDCARD.
1. Informações correspondentes a Idcard
Há um relacionamento individual entre a classe Idcard.java, a classe Idcard e a classe Pessoa. Portanto, o atributo de pessoa correspondente deve ser adicionado à classe Idcard. Isso é para adicionar os atributos correspondentes às chaves estrangeiras no arquivo de mapeamento e definir a classe de associação de chave estrangeira correspondente.
pacote com.src.hibernate; classe pública IDCARD {// ID ATRIÇÃO PRIVADO INT ID; public int getId () {return id; } public void setId (int id) {this.id = id; } // Atributo do número do cartão Private String Cardno; public String getCardno () {return Cardno; } public void setCardno (string cardno) {this.cardno = cardno; } // pessoas correspondentes ao número do cartão Pessoa privada; public Person getPerson () {Return Pessoa; } public void setPerson (pessoa da pessoa) {this.person = pessoa; }}O arquivo de mapeamento Idcard.hbm.xml adiciona uma pessoa de atributo de chave estrangeira ao arquivo de mapeamento e adiciona a tag <ene-to-one> correspondente. O objetivo é forçar a Classe Pessoa de Restrição a alcançar um relacionamento de mapeamento individual. Finalmente, defina o atributo restrito para True no mapeamento para garantir o relacionamento de restrição forçada.
<? xml versão = "1.0"?> <! Doctype hibernate-mapping público "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! <hibernate-mapping> <classe name = "com.src.hibernate.idcard" tabela = "idcard"> <id name = "id" type = "int" column = "personid"> <gerator> <param name = "propriedade"> pessoa </am param> </generator> </id> <names <bardno> "type"> "string" ">" string </param> </generator> </id> <name "- "cardno" "type"> " restrito = "true"> </one-one> </s class> </hibernate-mapping>
2. Informação correspondente da pessoa
Na classe Pessoa.java, além de adicionar atributos básicos, a classe IDCard correspondente deve ser adicionada como atributos, porque eles são um relacionamento de associação bidirecional individual, para que a classe Idcard também deve ser adicionada à classe Pessoa. O mesmo motivo é que os atributos da classe de pessoa também são adicionados à classe Idcard.
pacote com.src.hibernate; public class Pessoa {// ID Número privado Int ID; public int getId () {return id; } public void setId (int id) {this.id = id; } // Nome do nome da string privada; public String getName () {Return Name; } public void setName (nome da string) {this.name = name; } // IDCARD IDCARD PRIVADO IDCARD; public Idcard getIdCard () {return iDcard; } public void SetIdCard (IDCARD IDCARD) {this.idcard = IDCARD; }}Person.hbm.xml O arquivo de mapeamento, a estratégia de geração de chaves primária nesse arquivo não possui requisitos especiais porque é mutuamente restrito pela classe Idcard. Sua chave primária e a chave estrangeira são a chave primária do IDCARD. Além disso, como é um relacionamento individual, a tag <neone-one> deve ser adicionada ao arquivo de mapeamento para indicá-lo.
<? xml versão = "1.0"?> <! Doctype hibernate-mapping público "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! <hibernate-mapping> <classe name = "com.src.hibernate.person" table = "pessoa"> <id name = "id" type = "int" column = "Personid"> <Gerator> </generator> </id> <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <) <). Por padrão, ele carrega de acordo com a chave primária, ou seja, obtém o valor do campo de relacionamento e carrega o objeto associado de acordo com a chave primária do oponente-> <One-to-one name = "Idcard"> </one-one> </s class> </hibernate-mapping>
3. Arquivo de mapeamento de hibernato
Após a configuração da classe acima e do arquivo de mapeamento, as informações sobre o mapeamento do banco de dados no hibernate.cfg.xml são necessárias para adicionar dois arquivos de configuração ao arquivo de configuração do hibernato, para que os itens de geração correspondentes possam ser encontrados ao gerar o banco de dados correspondente.
<? xml versão = "1.0" coding = "utf-8"?> <! <Session-Factory> <propriedade name = "hibernate.connection.driver_class"> com.mysql.jdbc.driver </property> <propriedade name = "hibernate.connection.url"> jdbc: mysql: // localhost: 3306/hibernate_one2_pk1 name = "hibernate.connection.username"> root </propriedade> <propriedade name = "hibernate.connection.password"> 1234 </propriedade> <propriedade name = "hibernate.dialect"> org.hibernate.dialect.mqldialect </propriedade> <papping Resource = "com/sring/srypt" hiMEct/srate/srate.mlept.mlept.mlept.mlept.mlept.mlept.mate (srate) Resource = "com/src/hibernate/idcard.hbm.xml"> </mapping> </session-factory> </ hibernate-configuration>
4. Gere resultados
Após a conclusão da configuração, você pode gerar o banco de dados correspondente a partir do conteúdo acima. No banco de dados, ele gerará a estrutura da tabela correspondente de acordo com o conteúdo configurado e há teclas estrangeiras correspondentes e campos de chave primária na tabela. Ao gerar a estrutura da tabela, o Hibernate produzirá a instrução SQL correspondente no console, como segue:
ALTER TABLE IDCARD DROP CHAVE ESTRAUGA FK806F76ABAC038CD8 Tabela de gota se existir tabela de gota de Idcard Se existir pessoa Criar tabela IDCARD (Pessoid inteiro não nulo, cardno varchar (255), chave de pessoa (personalidade) criar tabela (pessoa integrada), não -nulo (255), a chave de pessoa (personagem) criar tabela de tabela (pessoa integrada), não -nula (255), al -flect (personid)) criar uma pessoa com a tabela (não -nula (255), a tecla de identificação (PERSONID) Crie a tabela (a pessoa inteira), não FK806F76ABAC038CD8 (PERSOLID), Adicione restrições FK806F76ABAC038CD8 CHAVE ESTAGENTE (PESOLE) PESSOON (PESOLE)
A estrutura de tabela gerada é como mostrado na figura:
A chave primária PersonID é gerada em ambas as tabelas ao mesmo tempo e também é a chave estrangeira correspondente. Também restringe as teclas primárias das duas tabelas ao mesmo tempo e é único.
5. Teste de gravação e carga
Depois de gerar a tabela, escreva a tabela e leia os dados da tabela, escreva a classe de teste correspondente e o teste usa testes de unidade e grava os métodos de teste correspondentes.
5.1 Teste de gravação
Ao gravar no banco de dados, observe que os dois objetos escritos devem ser convertidos para o estado do treinador correspondente, caso contrário, ocorrerá um erro de conversão de estado. O código de teste é o seguinte:
public void testSave1 () {sessão session = null; tente {// crie uma sessão de sessão session = hibernateUtils.getSession (); // Ativar sessão de transação de sessão.begintransaction (); // Crie um objeto de pessoa e salve pessoa = new pessoa (); pessoa.SetName ("Zhangsan"); session.Save (pessoa); // Crie um objeto Idcard e salve IDCARD IDCARD = new Idcard (); idcard.setCardno ("11111111111111"); idcard.setPerson (pessoa); session.Save (IDCARD); // Envie transações e modifique a sessão de banco de dados.gettransaction (). Commit (); } catch (Exceção e) {// Mensagem de erro de impressão E.PrintStackTrace (); // rollback de negócios session.gettransaction (). Rollback (); } finalmente {// feche a sessão hibernateUtils.closSession (sessão); }} Os dados inseridos são mostrados abaixo:
5.2 Teste de carregamento
Escreva um método de carregamento. Como o relacionamento da associação é bidirecional, a operação de carregamento correspondente deve ser carregar a outra extremidade através de uma extremidade, ou seja, obter a classe Pessoa correspondente e obter as informações correspondentes do IDCard através da classe Pessoa. O oposto também deve ser verdadeiro, o código é o seguinte:
public void testLoad1 () {sessão session = null; tente {// crie uma sessão de sessão session = hibernateUtils.getSession (); // Ativar sessão de transação de sessão.begintransaction (); // Obtenha o objeto de pessoa e salve a pessoa = (pessoa) session.load (Person.class, 5); System.out.println ("idcard.id:"+Person.getIdCard (). GetId ()); System.out.println ("Idcard.cardno:"+PERSON.GETIDCARD (). Getcardno ()); // Crie um objeto Idcard e salve IDCARD IDCARD = (IDCARD) session.load (Idcard.class, 5); System.out.println ("Person.id:"+Idcard.getPerson (). GetId ()); System.out.println ("Person.name:"+idcard.getPerson (). GetName ()); // Envie transações e modifique o banco de dados session.gettransaction (). Commit (); } catch (Exceção e) {// Mensagem de erro de impressão E.PrintStackTrace (); // rollback de negócios session.gettransaction (). Rollback (); } finalmente {// feche a sessão hibernateUtils.closSession (sessão); }} Execute o método de teste acima e imprima o conteúdo relevante no console da seguinte forma:
2. Relacionamento de chave estrangeira bidirecional
Associação de chave estrangeira bidirecional pode ser entendida como um caso especial de associação de chave estrangeira. Essa especialidade é principalmente porque é uma correspondência bidirecional. No artigo anterior, foi mencionado que, se você deseja adicionar um campo de chave estrangeira a uma tabela, poderá usar a tag <fast-to-one>, que gerará a coluna de chave estrangeira correspondente no modelo de relacionamento. Esta tag deve ser usada se você deseja obter associação de chave estrangeira bidirecional.
1. Modelo de objeto
Vamos primeiro olhar para o modelo de objeto. Pessoas e cartões de identificação são um relacionamento individual. Uma pessoa corresponde a uma identidade; portanto, os multiplexes entre elas são individuais, e essa correspondência é de mão dupla. Portanto, seu modelo de objeto é o mesmo que a chave primária bidirecional, um para um, como mostrado na figura abaixo:
2. Modelo relacional
O modelo de relacionamento correspondente mudará bastante. O relacionamento de chave estrangeira individual gerará a chave estrangeira correspondente em uma tabela. Quando você recebe a pessoa e o cartão de identificação, significa que haverá uma coluna de chave primária do número do cartão de identificação no modelo de relacionamento, e uma situação de duas vias é formada entre eles, como mostrado na figura abaixo:
A correspondência entre eles é como visto na figura acima. Existe a chave primária da tabela Idcard na tabela de pessoas, formando um relacionamento de associação principal individual e é bidirecional. Ou seja, o IDCARD pode ser obtido através da pessoa, e a pessoa também pode ser obtida através do IDCARD.
O código no objeto Pessoa e o objeto Idcard é o mesmo que o código do objeto no artigo anterior. Não está listado no código. A única diferença é o problema de configuração no arquivo de mapeamento.
3. Arquivos de mapeamento
Idcard.hbm.xml Arquivo de mapeamento. A tabela Idcard não é a tabela principal do mapeamento; portanto, ao fazer um mapeamento individual, você precisa usar a tag <ene-to-one> para configurá-la e precisa formular atributos de chave estrangeira no modelo de relacionamento da pessoa. 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 -> <Hibernate-mapping> <classe name = "com.src.hibernate.idcard" tabela = "idcard"> <id name = "id" type = "int"> <generator /> < /id> <names name = "cardno" type = "java.lang.string" >-nen Name = "cardno" /"> < /" Property-ref = "Idcard"> </one-one> </s class> </hibernate-mapping>
Person.hbm.xml Arquivo de mapeamento, a tabela Pessoa é a tabela principal do mapeamento. Uma coluna de atributo de chave estrangeira precisa ser adicionada à tabela para indicar a tabela Idcard. Portanto, a tag <fast-to-one> precisa ser usada aqui para gerar a chave estranha correspondente no objeto de pessoa e exclusiva também deve usar exclusivo para indicar que o atributo é único.
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeamento dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate -> <Hibernate-mapping> <classe name = "com.src.hibernate.person" table = "pessoa"> <id name = "id" type = "int" column = "Personid"> <gerator /> < /id> <names name = "name" type = "java.lang.string"> name <bumn name = "" /"> < /name" /" column = "idcardno" uncel = "true" não-null = "true"> </fast-to-one> </s class> </hibernate-mapping>
A configuração do arquivo de mapeamento do objeto é concluída e, em seguida, um modelo relacional é gerado. A declaração SQL é a seguinte:
alter table PERSON drop foreign key FK8C768F55794A52CA drop table if exists IDCARD drop table if exists PERSON create table IDCARD (id integer not null auto_increment, CARDNO varchar(255), primary key (id)) create table PERSON (personId integer not null auto_increment, NAME varchar(255), idCardNo integer not null unique, primary key (PersonID)) ALTER TABLE PESSOON ADD INDEX FK8C768F55794A52CA (IDCARDNO), Adicione restrições FK8C768F55794A52CA Key estranho (IDCARDNO) Referências IDCARD (ID)
A instrução SQL gerada é antes de tudo a tabela criada. Ao criar a tabela, a coluna da chave primária é especificada. Após a conclusão da criação, as duas tabelas são modificadas para especificar atributos de chave estrangeira para formar um relacionamento individual.
Escreva um método de teste, adote testes de unidade, carregue objetos de duas classes e obtenha outro objeto de uma extremidade do objeto, respectivamente
// Carregar o objeto e carregar o objeto Pessoa usando o objeto IDCARD Public void testLoad1 () {session session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // Obtenha o objeto Idcard e obtenha o objeto de pessoa associado exclusivamente ao objeto no IDCARD IDCARD IDCARD = (IDCARD) session.load (idcard.class, 1); System.out.println ("Person.id ="+Idcard.getPerson (). GetId ()); System.out.println ("idcard.person.name ="+idcard.getperson (). GetName ()); // objeto getPerson e obtenha o objeto Idcard que está associado exclusivamente a ele na pessoa do objeto de pessoa = (pessoa) session.load (Person.class, 1); System.out.println ("idcard.id:"+Person.getIdCard (). GetId ()); System.out.println ("Idcard.cardno:"+PERSON.GETIDCARD (). Getcardno ()); // comprometer a transação session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }} Conteúdo gerado:
Comparando as duas relações de mapeamento, a chave primária e as relações de mapeamento de chaves estrangeiras são as relações de mapeamento bidirecional e o relacionamento de mapeamento precisa ser configurado ao mesmo tempo nas duas extremidades do objeto. A diferença é que a chave primária precisa usar apenas <neone-one>, porque não precisa gerar colunas de atributo, mas a estratégia de geração de chave primária estrangeira deve ser usada para a chave primária da tabela e o objeto de chave estrangeira está marcada; A estratégia de geração de chaves estrangeiras precisa usar a tag <Many-to-One> para gerar novas colunas de chave estrangeira.
Conclusão
O mapeamento individual em uma associação bidirecional foi discutido até agora. Os dois artigos discutem principalmente dois usos de uma associação de mão dupla. De fato, ainda é muito simples. Lembre-se de usar a tag <Many-to-One>, se desejar gerar uma chave estrangeira. Se for único, adicione o atributo exclusivo. A tag <ene-to-one> indica apenas um relacionamento individual. Ele indica apenas como um objeto carrega outro objeto e não adiciona uma nova coluna no modelo de relacionamento. O próximo artigo discutirá relacionamentos um para muitos.