Interceptor
Falando em interceptador, acredito que os sapatos infantis familiarizados com o Struts2 estão definitivamente familiarizados com o Struts2. O STRUTS2 pode personalizar o interceptador para executar uma série de trabalhos relacionados que você deseja. E o interceptador que estamos falando aqui também tem funções semelhantes.
Sem dizer bobagem, basta o código:
A seguir, a classe MyInterceptor, que implementa a interface interceptores:
public String onPreparestatement (String arg0) {return arg0; } public boolean onsave (objeto arg0, serializável arg1, objeto [] arg2, string [] arg3, type [] arg4) lança callbackexception {if (arg0 instanceof user) {system.out.println ("usuário a ser salvo =>"+(user) arg0) .getname ();); } retornar false; } Não leio outros métodos, basta seguir a implementação padrão. Precisamos apenas alterar esses dois métodos. Precisamos alterar o valor de retorno no OnProparestatement para retornar a instrução SQL atual. Os parâmetros são a instrução SQL executada passada. Podemos imprimir a instrução retornando diretamente.
Em Onsave, você pode dizer que é chamado ao salvar. Podemos fazer uma série de trabalhos de pré-preservação.
Eu acredito que todos podem entender isso olhando para os nomes dos parâmetros.
Serializável refere -se ao parâmetro do número da sequência, que se refere aos atributos que mapeiam para o ID do banco de dados.
Objeto [] Esta é uma série de estados, que não tem sido usada muito por enquanto. Vou estudá -lo mais tarde. No entanto, a API explica que, não importa como o valor nessa matriz é modificado, o método Onsave deve retornar verdadeiro.
String [] refere -se ao nome do atributo e do tipo [] é o tipo do atributo correspondente.
1) Este interceptador pode fazer algumas operações correspondentes antes e depois de salvar o banco de dados. Por exemplo, se você deseja modificar os dados e adicionar prefixo ou sufixo, poderá usá -los para implementá -los. Vamos dar uma olhada abaixo.
public boolean onsave (objeto arg0, serializável arg1, objeto [] arg2, string [] arg3, type [] arg4) lança callbackexception {if (arg0 instanceof user) {system.out.println ("usuário a ser salvo =>"+(user) arg0) .getName ()); } // Adicionamos 123 como o prefixo do nome aqui usuário usuário = (usuário) arg0; user.setName ("123"+user.getName ()); retornar falso; }Vamos dar uma olhada no método de teste:
public static void main (string [] args) {Configuration cfg = new Configuration (). Configure (); Sessionfactory sessfactory = cfg.buildSessionFactory (); Interceptador interceptador = new MyInteceptor (); Sessão session = sessionFactory.opensssion (interceptor); Usuário do usuário = novo usuário (); user.setName ("Shun"); Transação tx = session.begIntransaction (); session.Save (usuário); tx.Commit (); session.close (); } É muito simples, apenas o salvamos. Não há arquivos de mapeamento e aulas de entidade aqui, basta experimentar.
Execute -o e podemos ver:
Usuário a ser salvo => Shun Hibernate: Insira no usuário (user_name, idade) onde user_id =?Ele atualizará o nome e a idade no final, principalmente porque fizemos alterações no método Onsave.
public boolean onLload (objeto arg0, serializável arg1, objeto [] arg2, string [] arg3, tipo [] arg4) lança callbackexception {if (arg0 instanceof user) {system.out.println ("usuário a ser carregado =>"+(arg2 [0]+":"+arg2 [1]); } Usuário usuário = (usuário) arg0; // julga qual atributo é nome para (int i = 0; i <arg3.Length; i ++) {if (arg3 [i] .equals ("name")) {user.setName ((string) arg2 [i]). Substituir ("123", "")); arg2 [i] = (((string) arg2 [i]). substituir ("123", ""); }} retornar false; } O valor do atributo modificado quando o carregamento é gravado no método Onload.
O arg0 aqui é o nosso objeto de usuário. Ainda não tem valor. Esse método é chamado após o método de carga, por isso é inútil para operarmos o usuário no momento, e o user.setName aqui é uma operação inútil. Principalmente em:
arg2 [i] = (((string) arg2 [i]). substituir ("123", "");
Esse código altera o valor do atributo retornado; portanto, o valor no objeto do usuário que obtemos no programa também mudará. Vamos executar o método de teste para ver:
public static void main (string [] args) {Configuration cfg = new Configuration (). Configure (); Sessionfactory sessfactory = cfg.buildSessionFactory (); Interceptador interceptador = new MyInteceptor (); Sessão session = sessionFactory.opensssion (interceptor); Usuário do usuário = (usuário) session.load (user.class, novo long (39)); System.out.println ("Nome do usuário:"+user.getName ()); session.close (); }Olhando para os resultados, obtivemos:
Hibernate: selecione User0_.user_id como user1_0_0_, user0_.user_name como user2_0_0_, user0_.age como idade0_0_ do usuário user0_ where user0_.user_id =? Usuário a ser carregado => 123shun: 0 Nome do usuário: Shun
Removemos o 123 original e realizamos processamento relevante após o carregamento real, mas esse não é um processamento real antes do carregamento real e suspeita de especulação. Mas também é uma consideração. O interceptador pode ser usado mais no processamento relevante de logs. Por exemplo, precisamos registrar correspondentemente para cada operação, portanto, o Interceptor é uma boa escolha.
Coleção
Lembre-se do conjunto que usamos em um para muitos nos exemplos anteriores, você ainda tem a impressão? Caso contrário, verifique as informações e revise -as. Hoje vamos aprender em torno dessas coleções.
Vamos apenas chegar ao ponto.
1) Primeiro, vamos aprender. Todo mundo sabe que também há um conjunto no pacote Java UTIL. Então, qual é a diferença e a conexão entre o conjunto e o conjunto no hibernado? Abrimos a API Hibernate, encontramos o conjunto e você pode vê -lo.
O que vemos é a classe pai de uma coleção de hibernato. É uma classe abstrata com uma série de classes de implementação concreta. Quando continuamos a ver o método a seguir, descobrimos que essa classe implementa o encapsulamento da coleção Java, para que entendemos que o chamado conjunto de hibernados realmente encapsula apenas o conjunto Java.
Então, essa característica é que não permite elementos duplicados no conjunto também em Hibernate? A resposta é claro que sim.
Não olhamos para isso aqui. No passado, quando aprendemos o mapeamento, associamos as propriedades diretamente às classes associadas, mas hoje não somos assim. Usamos outro método, basta associar uma string para ver se há algum problema.
Mas antes de olhar para essa pergunta, vamos dar uma olhada na comparação de strings em Java.
O que vemos é a classe pai de uma coleção de hibernato. É uma classe abstrata com uma série de classes de implementação concreta. Quando continuamos a ver o método a seguir, descobrimos que essa classe implementa o encapsulamento da coleção Java, para que entendemos que o chamado conjunto de hibernados realmente encapsula apenas o conjunto Java.
Então, essa característica é que não permite elementos duplicados no conjunto também em Hibernate? A resposta é claro que sim.
Não olhamos para isso aqui. No passado, quando aprendemos o mapeamento, associamos as propriedades diretamente às classes associadas, mas hoje não somos assim. Usamos outro método, basta associar uma string para ver se há algum problema.
Mas antes de olhar para essa pergunta, vamos dar uma olhada na comparação de strings em Java.
public static void main (string [] args) {string s1 = "shun1"; String s2 = "shun1"; System.out.println ("S1 == S2:"+(S1 == S2)); } Eu acredito que os sapatos de muitas crianças sabem que a resposta é verdadeira.
Antes de fazer um exemplo, vamos dar uma olhada no nosso arquivo de mapeamento. Não escreveremos as aulas de mapeamento:
Este é o arquivo de mapeamento para o minimensional:
<classe name = "Tuser" tabela = "t_user" dinâmico-insert = "true" dinâmico update = "true" dynamic update = "true"> <id name = "id" column = "id"> <generator/> </id> <nome da propriedade "name" type = "james.lang.string" column = "" " colun = "idade"/> <set name = "endereços" cascade = "all" tabela = "t_address"> <key column = "user_id"/> <!-<One-to-many/>-> <elemento column = "endereço" type = "string"/> </set> </classe>
Em seguida é o arquivo de mapeamento de endereço:
<class name="Address" table="t_address" dynamic-insert="false" dynamic-update="false"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <property name="address" column="address" type="java.lang.String" /> <many-to-one name="user" column="user_id" não-null = "true"> </fast-tone> </s class>
Os sapatos das crianças viram isso claramente. Eu comentei um para muitos no conjunto no Docimento e usei o elemento. Não importa qual seja o problema, vejamos primeiro o banco de dados:
Esta é a tabela T_Address:
Aqui está a tabela T_USER:
Podemos ver que o usuário com ID 4 corresponde a três endereços. Em seguida, vamos dar uma olhada no método de teste:
public static void main (string [] args) {Configuration cfg = new Configuration (). Configure (); Sessionfactory sessfactory = cfg.buildSessionFactory (); Sessão session = sessionFactory.opensssion (); Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); Set set = user.getAddresses (); session.close (); System.out.println ("Tamanho do endereço:"+set.size ()); } Uma aula de consulta muito simples, acabei de fazer esse resultado, vimos um fenômeno estranho:
Tamanho do endereço: 1
Este é o resultado!
Você definitivamente dirá que deve estar errado, é um bug no hibernado. Devo ser feliz aqui. Eu posso finalmente enviar um bug. Quando mudei de emprego, pude dizer em voz alta que enviei um bug para o Hibernate. Haha, mas infelizmente, isso não é um bug.
Acabei de dizer que a comparação da corda que tínhamos na frente estava pavimentando o caminho aqui, então como pavimentar?
Usamos o conjunto definido no arquivo de configuração e o associamos através de caracteres da string. Então, quando for retirado no banco de dados e o coloca no conjunto, primeiro determinará se os valores do caractere associado são iguais. Aqui, como nossos valores são iguais (não vamos investigar como ele se compara por enquanto), só precisamos saber que, quando usamos strings para comparar, caímos na armadilha de string em Java novamente. Se você descobrir que existe apenas um, a exclusão é mais problemática ao excluí -la, ela excluirá todos os mesmos registros.
Então vamos dar uma olhada no excluído:
Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); Transação tx = session.begIntransaction (); Objeto obj = user.getAddresses (). Iterator (). Next (); user.getAddresses (). Remover (obj); tx.Commit (); session.close ();
A saída da declaração por Hibernate aqui é:
Hibernate: exclua do t_address onde user_id =?
Acredito que todo mundo sabe quando é excluir todos os endereços sob o usuário. Não há escolha a não ser excluir tudo isso.
Então você precisa prestar atenção a ele em desenvolvimento real.
2) Conversamos sobre o conjunto acima, parece que não é muito agradável de usar. Existe uma armadilha, mas não há como. O conjunto é o que mais usamos, e geralmente ninguém associa diretamente strings. Mas muitas pessoas ainda estão infelizes, então o Hibernate terá uma bolsa extra conforme necessário (talvez não seja o necessário, talvez algumas pessoas sejam insatisfeitas, haha).
Vamos primeiro olhar para seu uso básico:
Primeiro, precisamos modificar a tag definida no arquivo de mapeamento anterior de Discover para:
<bag name = "endereços" lazy = "true" tabela = "t_address"> <key column = "user_id" /> <elemento tipo = "string" column = "endereço" /> </bag>
E a classe de entidade correspondente precisa modificar o tipo de endereço para o tipo de lista.
Aqui adicionamos três endereços:
Nós executamos o código de teste:
public static void main (string [] args) {Configuration cfg = new Configuration (). Configure (); Sessionfactory sessfactory = cfg.buildSessionFactory (); Sessão session = sessionFactory.opensssion (); Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); System.out.println ("Tamanho do endereço:"+user.getAddresses (). Size ()); session.close (); }
Aqui vemos:
Tamanho do endereço: 3
Desta vez, podemos ver tudo, independentemente de haver alguma repetição ou não.
Mas apenas analisamos um problema de exclusão. A bolsa não foi resolvida aqui e precisamos usar o IDBag. Vemos o arquivo de configuração e precisamos das seguintes modificações:
Idbag name = "endereços" tabela = "t_address" lazy = "true"> <coletor-id type = "int" column = "id"> <gerator /> < /collection-id> <key colun = "user_id" /> <elemento tipo = "string" column = "endereço" /> < /idbag>
Vemos que ele possui apenas mais um ID da coleção do que a bolsa para indicar o número recorde a ser excluído.
Quando executamos o código excluído:
Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); Transação tx = session.begIntransaction (); Objeto obj = user.getAddresses (). Iterator (). Next (); user.getAddresses (). Remover (obj); tx.Commit ();
Vemos que a declaração de saída é:
Hibernate: exclua de t_address onde id =?
Desta vez, ele não é excluído através do user_id, mas com base no ID do T_Address, o que significa que realmente exclui o registro que precisamos excluir.
Vemos o banco de dados e o registro é agora:
Excluímos o primeiro registro, está correto.
3) Depois de olhar para os dois métodos acima, vamos dar uma olhada no mapa. A maior diferença entre ele e os dois acima é que ele pode corresponder aos valores -chave. Olhe diretamente para o código, ponto de vista intuitivo:
Primeiro, precisamos modificar o arquivo de configuração:
<mapa name = "endereços" tabela = "t_address" lazy = "true"> <key colun = "user_id" /> <index type = "string" column = "type" /> <elemento tipo = "string" column = "endereço" /> < /map>
A maior diferença entre ele e os dois anteriores é que existe um índice, que é equivalente à chave do mapa em Java, e usamos isso para recuperar os registros correspondentes. Lembre -se, depois de mudar aqui, você precisa alterar a classe de entidade correspondente e precisa alterar o tipo de atributo de endereços para o mapa.
Veja os dados do banco de dados:
Aqui vemos que existem dois escritórios e uma casa, então qual escritório deve ser usado?
Não se preocupe, saberemos depois de executar o código de teste:
Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); System.out.println (user.getAddresses (). Get ("home")); System.out.println (user.getAddresses (). Get ("Office"));Shanwei Shanghai
Sim, como mostra o resultado, ficamos atrás, o mesmo que o princípio do mapa. Os valores armazenados substituirão os valores anteriores (se forem a mesma chave).
O mapa é relativamente simples, que é comparável aos dois primeiros.
4) Vamos dar uma olhada no último. A lista é diferente dos anteriores e pode ser classificada.
Vamos dar uma olhada em como é implementado:
Primeiro, vamos modificar o arquivo de mapeamento:
<list name = "endereços" tabela = "t_address" lazy = "true"> <key column = "user_id" /> <index type = "string" column = "idx" /> <elemento tipo = "string" column = "endereço" /> < /list>
É semelhante à configuração do mapa, mas os atributos do índice são diferentes. O índice no mapa é usado como uma chave para obter o valor, enquanto o índice de lista é usado como classificação.
Vejamos o banco de dados:
Definimos três valores na ordem de 0, 1 e 2.
Vamos executar o código para alterar os valores de 0 e 2:
Usuário do Divulgo = (Dividir) session.load (Tuser.class, novo número inteiro (4)); Transação tx = session.begIntransaction (); Objeto obj1 = user.getAddresses (). Get (0); Objeto obj2 = user.getAddresses (). Get (2); user.getAddresses (). set (0, obj2); user.getAddresses (). set (2, obj1); tx.Commit ();
Vemos os resultados:
Vemos que 0 e 2 foram substituídos e, é claro, isso está apenas mudando o valor do IDX. Mas isso basicamente implementou a função de classificação.