O Hibernate conduziu classificação e integração e descobriu que o hibernato é realmente dividido em três partes: objeto principal, mapeamento e HQL. Essas três partes são mais comumente usadas no processo de desenvolvimento. Os artigos anteriores discutem os métodos de conversão entre objetos e objetos principais. Em seguida, discuta os métodos de uso de hibernato de mapeamento.
Uma função importante do hibernato é o mapeamento, que pode converter entre o modelo de objeto e o modelo relacional. É defendido por idéias de programação orientadas a objetos. Os desenvolvedores que usam programas de mapeamento só precisam se preocupar com a redação do código no modelo de objeto. O mapeamento entre um objeto e um banco de dados relacional é geralmente definido por um documento XML. Este documento de mapeamento foi projetado para ser legível e pode ser modificado manualmente. Eu resumi essa relação de mapeamento, como mostrado na figura a seguir:
O mapeamento é definido através do XML, gerenciado usando a sessão criada pelo Hibernate e, finalmente, a sessão usa o JTA para enviar as alterações no banco de dados. A sessão pode ser entendida como gerente de persistência, que gerencia objetos na camada de persistência. É criado pelo SessionFactory. Ao programar com o Hibernate, você deve primeiro conectar -se ao banco de dados; portanto, verifique primeiro a configuração da conexão do banco de dados no XML, crie uma sessão de session de acordo com a configuração do documento (que pode ser entendida como um espelho de banco de dados) e, em seguida, criar um SessionFactory. Por fim, a sessão enviará as alterações no banco de dados uniformemente, o que concluirá todas as operações.
Processo de uso
1. Crie um arquivo de mapeamento e o arquivo de mapeamento é sufixo com .hbm.xml, indicando que é um arquivo de mapeamento de hibernato;
2. Registre a classe de entidade no arquivo de mapeamento e adicione as propriedades da classe de entidade à classe de mapeamento. Ao adicionar propriedades, você deve especificar dois valores: ID e propriedade. O ID indica que é o único identificador de uma entidade, e a propriedade indica que é uma coluna de campo da tabela;
3. Envie modificações e sincronize dados.
Nota: Os desenvolvedores que desenvolveram dados XML para o banco de dados entenderão em breve que esse mapeamento é na verdade um processo de atualização em lote e criação de lote, e o mapeamento não é exceção. Hibernate estipula um conjunto de padrões de mapeamento que podem ser convertidos de acordo com os padrões. Sua implementação interna ainda está morta, por isso é apenas relativamente flexível e fácil de usar.
Um processo de mapeamento de classe de entidade simples:
1. Código da propriedade da classe Classe Usuário1:
pacote com.hibernate; importar java.util.date; classe pública user1 {private string id; nome de string privado; senha de sequência privada; data privada createTime; data privada expireTime; public string getId () {return id; } public string getName () {return name; } public void setName (nome da string) {this.name = name; } public string getPassword () {return senha; } public void setPassword (string senha) {this.password = senha; } public data getCreateTime () {return createTime; } public void setCreateTime (data createTime) {this.createTime = createTime; } public data getExpireTime () {return expireTime; } public void setexpireTime (data expireTime) {this.expiretime = expireTime; }}
2. A implementação do código interno do usuário1.hbm.xml do arquivo de mapeamento user1.java:
As configurações que podem ser definidas no banco de dados básicas também são fornecidas no Hibernate. Você pode usar atributos do rótulo para definir relacionamentos específicos de mapeamento.
Classe-> As tabelas usam tags de classe, propriedades comumente usadas:
(1) Nome: Classe de entidade do mapa, seu valor precisa ser definido com o nome da classe de entidade que precisa ser convertida em uma tabela. Durante a sincronização, a classe de entidade correspondente será encontrada com base nesse atributo.
(2) Tabela: Mapeie o nome da tabela de banco de dados. Se o nome da tabela a ser mapeado for diferente do nome da classe da entidade, use esta propriedade para especificar a tabela mapeada. Se não existir, uma tabela será criada com base no valor da propriedade.
Verifique a estrutura da tabela gerada pela configuração na figura acima, como mostrado abaixo:
O nome da tabela é alterado para T_USER1; O campo de identificação é alterado para user_id e o comprimento do campo é de 32 bits; A propriedade CreateTime é mapeada para o campo do banco de dados create_time e é modificada até o tipo de data.
Propriedade -> Campos usam id ou tags de propriedade, propriedades comumente usadas:
(1) Nome: A função é semelhante ao nome da tag de classe e o valor determina o nome do atributo de mapeamento da classe de entidade;
(2) Coluna: semelhante à tabela da tag da classe da entidade, especificando o nome da coluna da tabela de mapeamento e será criada se não existir;
(3) TIPO: Especifique o tipo de dados mapeado para campos no banco de dados e visualize o documento conforme necessário;
(4) O gerador, que é opcional, é usado para gerar um identificador exclusivo para uma classe persistente.
<id name = "id" type = "long" colun = "cat_id"> <gerator> <param name = "tabela"> uid_table </param> <param name = "column"> next_hi_value_column </am Param> </generator> </dd>
Todos os geradores implementam a interface org.hibernate.id.entifierGenerator. Esta é uma interface muito simples; Alguns aplicativos podem optar por fornecer sua própria implementação específica. Obviamente, o Hibernate fornece muitas implementações internas. Aqui estão alguns tipos comumente usados:
(1) Identidade: o identificador retornado é do tipo longo, curto ou int. Semelhante ao campo de auto-incremento do banco de dados.
(2) Sequência: Use sequências em DB2, PostgreSQL, Oracle, SAP DB, McKoi e geradores em interbase. O identificador retornado é do tipo longo, curto ou int. Em todo o banco de dados, em vez de auto-aumentar em uma única tabela, você precisa especificar que a auto-aumento de uma única tabela precisa ser adicionada.
(3) UUID: Use um algoritmo UUID de 128 bits para gerar um identificador de tipo de string, que é exclusivo em uma rede (usando um endereço IP). O UUID é codificado como uma sequência de números hexadecimais de 32 bits. Semelhante ao número de série gerado pelo .NET.
(4) Nativo: Escolha uma de identidade, sequência ou hilo com base nos recursos do banco de dados subjacente. De maneira flexível, o tipo de identidade usado será determinado com base no banco de dados usado. O MySQL selecionará a identidade e o Oracle selecionará a sequência.
(5) Atribuído: Crie manualmente um ID de identificação para a classe de entidade. Esta é a política de geração padrão quando o elemento <gerator> não é especificado.
(6) Estrangeiro: use outro identificador de objeto associado. Geralmente usado em combinação com <one-one>.
Os desenvolvedores são frequentemente usados no método de configuração manual para gravar propriedades de configuração de acordo com as instruções da documentação. Isso é muito primitivo. Os iniciantes recomendam o uso do método de configuração manual para ajudar a pensar. Existem também muitas ferramentas de terceiros que usam métodos visuais para configurar e gerar documentos de configuração XML, o que melhora a eficiência do desenvolvimento. Ferramentas semelhantes como XDoclet, Middlegen e Andormda.
Mapeamentos associativos são muitos para um
O mapeamento básico do hibernato é discutido acima. Uma classe de entidade corresponde a uma tabela e usa o mapeamento de tags <set> no arquivo de mapeamento de hibernato correspondente. E as propriedades normais na classe de entidade correspondem ao campo da tabela e são mapeadas usando a tag <prompey>. Além disso, ao construir classes de entidade, você deve prestar atenção: o construtor padrão sem parâmetros deve ser implementado nas classes de entidade e um rótulo deve ser fornecido. Recomenda -se não usar o final para modificar a classe de entidade e gerar métodos Getter e Setter para a classe de entidade. Finalmente, várias estratégias principais de geração de chaves primárias são introduzidas e o próximo passo é discutir o mapeamento de muitos para um.
Esse mapeamento de correlação muitos para um é refletido no modelo de objeto. É uma relação de agregação. O usuário faz parte do grupo. Existem usuários no grupo. Seus ciclos de vida são diferentes e podem ser refletidos na figura a seguir:
Então, como esse mapeamento de relacionamento muitos para um está definido em Hibernate? A seguir, introduzirá dois métodos: use a tag <Many-to-One> para mapear diretamente ou use a Cascada <Many-to-One> para modificar a tabela.
1. Muitos para um mapeamento direto <br /> pode ser entendido a partir do significado literal que se refere a um relacionamento de muitos para um. Muitos se referem ao fim, e um se refere ao menos. Ao usá-lo, a tag é frequentemente usada no HBM da extremidade mais final, e o atributo de nome de <Many-toOne> é definido como o atributo de uma extremidade de um na classe correspondente do arquivo de mapeamento, como: <many-tone name = "group" colun = "groupID"> </fast-to-one. Esta tag é adicionada ao usuário.hbm.xml, que corresponde a muitos; O valor do nome na tag é o grupo para mapear um, e haverá um atributo chamado grupo no user.java. Em seguida, vamos dar uma olhada na classe de código específica que implementa a implementação.
(1) Código de classe do user.java, que possui uma propriedade chamada Grupo, que será usada como o valor do nome da extremidade de <fast-to-one>.
Public class Usuário {Nome da String Private; public String getName () {Return Name; } public void setName (nome da string) {this.name = name; } Grupo Privado Grupo; grupo público getGroup () {return Group; } public void setGroup (grupo de grupo) {this.group = grupo; }}(2) O valor do nome de <far-tone> no user.hbm.xml é o valor da propriedade do lado único no user.java. Ele gerará uma nova coluna no banco de dados, que pode ser entendida como uma chave estrangeira da tabela de usuários.
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! -> <Hibernate-mapping> <classe name = "com.hibernate.user" tabela = "user"> <id name = "id" type = "java.lang.long"> <colun name = "id" /> <generator /> < /id> <!-O valor do nome é um imóvel em um correspondente em User.Java. Ele gerará automaticamente uma coluna na tabela, para que a coluna seja renomeada usando a coluna-> <many-tone name = "group" column = "groupId"> </anyst-to-one> </s class> </hibernate-mapping>
(3) Teste o relacionamento de mapeamento acima, escreva dois objetos de usuário na tabela, nomeie o usuário1 e o usuário2, nomeie -o Zhang San e Li Si, use sessão para salvar o objeto, gravar dados no banco de dados, o código é o seguinte:
public void testSave1 () {sessão session = null; tente {session = getSession.getSession (); session.BegIntransaction (); Grupo de grupo = novo grupo (); group.setName ("nó de energia"); Usuário do usuário1 = novo usuário (); user1.setName ("Zhang San"); user1.setGroup (grupo); Usuário usuário2 = novo usuário (); user2.setName ("li si"); user2.setGroup (grupo); session.Save (User1); session.Save (User2); // O erro transiEbjectException será relatado // O erro ocorre ao limpar o cache transienteObjectException // porque o grupo é um estado transitório, não é sessionado e não há dados correspondentes no banco de dados // quando o usuário é realizado em estado de referência ao objeto que não pode se referir ao objeto de referência a que o objeto de cache de cache //: objetos em que se referem a que se referem a que se referem a que há um estado de referência, não se refere a um estado de referência a que o objeto de que o hibernato se refere a um estado. session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {getSession.ClosSession (sessão); }}No entanto, ao usar o código acima, uma transientObjectException será relatada ao executar gravações. Isso ocorre porque, ao salvar o objeto do usuário, ele procurará objetos de grupo na memória de acordo com o grupo adicionado em <fre-tone>. No entanto, no código acima, o objeto do grupo sempre esteve no estado transitório e não é gerenciado pela sessão, o que significa que o objeto de sessão não pode ser encontrado e o objeto do usuário insere o estado persistente, portanto esse erro será relatado. O código correto é o seguinte:
public void testSave2 () {sessão session = null; tente {session = getSession.getSession (); session.BegIntransaction (); Grupo de grupo = novo grupo (); group.setName ("nó de energia"); session.Save (Grupo); // Defina o objeto do grupo aqui como o usuário do objeto persistente Usuário1 = new User (); user1.setName ("Zhang San"); user1.setGroup (grupo); Usuário usuário2 = novo usuário (); user2.setName ("li si"); user2.setGroup (grupo); session.Save (User1); session.Save (User2); // Os dados podem ser salvos corretamente // porque o grupo e o usuário são objetos em estado persistente // O objeto associado pode ser encontrado na sessão quando o hibernate limpa a sessão do cache.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {getSession.ClosSession (sessão); }} 2. Mapeamento em cascata
Além de converter o objeto do grupo e o objeto do usuário para o objeto persistente mencionado acima, você também pode usar os atributos de mapeamento em cascata em cascata, adicione o atributo Cascade no atributo <fam-to-one> e copie-o para salvar update. Você pode escrever no banco de dados quando o objeto do grupo não estiver no estado persistente. Dessa forma, você só precisa definir os atributos do grupo dos dois objetos de usuário para o mesmo objeto de grupo para obter um relacionamento de mapeamento de muitos para um. No momento, o conteúdo correspondente no usuário.hbm.xml é o seguinte código:
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! -> <hibernate-mapping> <classe name = "com.hibernate.user" tabela = "user"> <id name = "id" type = "java.lang.long"> <names de coluna = "id" /> <generator /> < /id> <!-tabela de modificação de cascade-> <mutuy-toone name = "grupo" grupo " </s Class> </ hibernate-mapping>
NOTA: Depois que a Cascade está definida como Savor-Update, ela pode ser modificação em cascata, adição e exclusão ao banco de dados, mas a operação específica de consulta em cascata não pode ser feita.
O método de arquivo de configuração de teste correspondente é o seguinte:
// Cascade Cascade Public void testSave3 () {sessão session = null; tente {session = getSession.getSession (); session.BegIntransaction (); Grupo de grupo = novo grupo (); group.setName ("nó de energia"); Usuário do usuário1 = novo usuário (); user1.setName ("Zhang San"); user1.setGroup (grupo); Usuário usuário2 = novo usuário (); user2.setName ("li si"); user2.setGroup (grupo); session.Save (User1); session.Save (User2); // A transientObjectException não foi jogada // porque a cascata é usada // hibernate salvará primeiro o grupo de objetos associados do usuário // grupo e o usuário são objetos em session de estado persistente.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {getSession.ClosSession (sessão); }} 3. Sublimação comparativa
Os dois métodos também implementam um método de mapeamento de muitos para um, e os resultados são os mesmos, mas são muito diferentes na implementação. Se o primeiro ou o segundo tipo usa <far-to-one> para adicionar a tag ao arquivo de mapeamento em muitas extremidades e atribuir o atributo de nome da tag ao valor do atributo da extremidade da classe registrada pelo arquivo de mapeamento, completando assim o mapeamento básico de muitos para um, o mesmo. A diferença é que o relacionamento de mapeamento direto não usa os atributos do campo Hibernate, que é mais flexível na implementação. Ele não apenas suporta adição, exclusão e modificação, mas também permite a consulta; A segunda modificação em cascata em cascata adota o método fornecido pelo Hibernate. Este método suporta apenas adição, exclusão e modificação e não suporta consulta.