A pesquisa neste artigo se concentra principalmente no mecanismo de cache de hibernato, como segue.
Estudante.java:
Public Class Student {/*ID do aluno*/Private Int ID;/*Nome do aluno*/Nome da sequência privada;/*Relacionamento entre estudantes e aula*/aulas particulares aulas; // omita Métodos de Setter e Getter}Classes.java:
Classes de classe pública {/*classe ID*/private int id;/*Nome da classe*/Nome da sequência privada;/*Relacionamento entre a classe e os alunos*/Conjunto privado <estudante> alunos; // omitir métodos de setter e getter}Student.hbm.xml:
<? 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"> <hibermate-mapping.netge.net/hibernate tabela = "t_student"> <id name = "id"> <generator // id> <!-mapear propriedades normais-> <propriedade name = "name"/> <!-mapeamento de muitos para one, adicione uma chave estranha ao fim múltiplo-> <many-one name = "classes" column = "clasesid"/> </class> </hibern
Classes.hbm.xml:
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate name = "Classes" tabela = "t_classes" lazy = "false"> <id name = "id"> <generator/generator/> </id> <propriedade name = "name"/> <!-One-to-gany mapeando, inverse = "true" significa de mãos dadas ao par de colunos-> <sett = "estudantes" em "" </set> </s class> </ hibernate-mapping>
O período de declaração do cache de primeiro nível é muito curto e o ciclo de vida da sessão é consistente. O cache de primeiro nível também é chamado de cache no nível da sessão ou cache no nível da coisa. O cache de primeiro nível é o objeto de cache e não pode cache os atributos.
Método de teste (Use Load () Consulta duas vezes na mesma sessão):
/*Depois de retirá -lo, ele será colocado no cache e, na segunda vez, buscará, será recuperado diretamente do cache*/ aluno estudante = (aluno) session.load (student.class, 1); System.out.println ("student.name =" + student.getName ()); /*Nenhuma declaração de consulta é emitida, o carregamento usa cache*/ aluno = (aluno) session.load (student.class, 1); System.out.println ("student.name =" + student.getName ());NOTA: Descobrimos que, quando consultarmos, os resultados encontrados serão colocados em sessão, cache e cache de nível um. Quando recebo o valor a tempo após o carregamento () na segunda vez, não emiti uma instrução para consultá -lo no banco de dados, mas recuperei diretamente o valor do cache (ele deve estar na mesma sessão).
Método de teste dois (na mesma sessão):
Estudante estudante = novo aluno (); estudante.setName ("Zhang San"); ID serializável = session.save (aluno); aluno = (aluno) session.load (student.class, id); // A declaração de consulta não será emitida porque o salvamento suporta cache System.out.println ("student.name =" + student.getName ());NOTA: O método SALVE () é chamado e Load () é usado para carregar o objeto e, em seguida, o atributo de nome é realmente obtido, mas nenhuma instrução é emitida para consultar o banco de dados. Porque o método save () também suporta cache.
Teste a adição de grandes lotes de dados:
public void testCache7 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); for (int i = 0; i <100; i ++) {Student = new Student (); estudante.setName ("Zhang San" + i); session.Save (aluno); // Atualize a cada 20 itens se (i % 20 == 0) {// Limpe o cache e, após chamar Flush, os dados serão salvos no banco de dados session.flush (); // limpe o conteúdo em cache session.clear (); }} session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }} Observação:
1. Como o método save () suporta cache, há um problema. Se eu quiser economizar 10 milhões de dados ao mesmo tempo, existem 10 milhões de objetos de cache no cache, o que provavelmente causará transbordamento. Portanto, o Hibernate não suporta a operação de atualização de dados em larga escala, mas também podemos lidar com esse problema com muita flexibilidade, como limpar o cache a cada 20 peças de dados usando um loop.
2. Métodos de salvar, atualizar, salvar, carregar, obter, listar, iterar, bloquear os métodos colocarão objetos no cache de primeiro nível. O cache de primeiro nível não pode controlar o número de caches, portanto, você deve prestar atenção à possibilidade de transbordar de memória ao operar dados em grandes lotes; Você pode usar o método de despejo e limpar para limpar o conteúdo no cache.
O cache secundário também é chamado de cache no nível do processo ou cache de nível de sessão, e o cache secundário pode ser compartilhado por todos os caches da sessão. O ciclo de vida do cache secundário é o mesmo que o da SessionFactory. O SessionFactory pode gerenciar o cache secundário. O princípio do cache secundário é usado quando a leitura é muito maior que a escrita. O cache secundário é usado principalmente para cache os objetos da entidade.
1. Copie o arquivo ehcahe.xml para o diretório SRC.
2. Adicione o provedor de produtos de cache ao arquivo hibernate.cfg.xml, como segue:
<propriedade name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </propriedade>
3. Ativar cache de nível 2 (não é possível exibir a inicialização, porque o padrão está ativado), como segue:
<Propriedade name = "hibernate.cache.use_second_level_cache"> true </ouse>
4. Especifique quais classes de entidade usam o Cache do Nível 2.
5. Importar o pacote JAR da interface usado pelo cache: lib/optional/ehcache/ehcache-core-2.4.3.jar
Conteúdo do arquivo ehcache.xml:
<DefaultCache maxElementsinMemory = "10000" eternal = "false" timeToidleSeconds = "120" timeToliveSeconds = "120" OverflowTodisk = "True" />
Observação:
1.MaxElementsInMemory representa os objetos mais armazenados no cache.
2.Esternal indica se nunca expirará (defini -lo como falso é mais prático. Se verdadeiro, nunca expirará, então os seguintes atributos não têm sentido).
3.TimeToidleSecods indica quanto tempo um objeto não foi acessado após a primeira vez que foi liberado.
4. TimetoliveSecods representa o tempo de inventário de um objeto.
5. O OverflowTodisk é verdadeiro, o que significa que o número no cache excede o número especificado por MaxElementsInMemory e é armazenado no disco.
Especifique o caminho do disco salvo no transbordamento:
<DiskStore Path = "java.io.tmpdir"/>
Nota: Este caminho pode ser alterado.
Método de teste (a premissa do cache de nível 1 é que ele deve estar na mesma sessão. Agora usamos o cache do Nível 2 para ver se há um cache em duas sessões diferentes):
public void testCache1 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); Student Student = (Student) session.load (student.class, 1); {E.PrintStackTrace (); session.gettransaction (). rollback ();} finalmente {hibernateUtils.clossession (session);} try {session = hibernateutils.getSession (); session.BegIntransaction (); Student = (Student) Sessão.Gent.class.cloust, 1); A sessão pode compartilhar os dados no cache secundário.// O cache secundário é um sistema de cache no nível do processo.out.println ("student.name =" + student.getName ()); session.getTransaction (). Commits ();} catch (exceção e) {ePrintStack); session. {Hibernateutils.clossession (sessão);}}Nota: Se o cache secundário estiver configurado, descobriremos que, mesmo que a primeira sessão esteja fechada e outra sessão seja ativada para carregar dados, ela não emitirá uma instrução para consultar os dados no banco de dados, porque o cache secundário está configurado, é compartilhado por todo o SessionFactory.
Desative o cache do nível 2 para implementar a adição de grandes lotes de dados:
public void testCache5 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // A interação do cache e do cache secundário é proibida session.setCachemode (Cachemode.ignore); for (int i = 0; i <100; i ++) {Student = new Student (); estudante.setName ("Zhang San" + i); session.Save (aluno); // Atualize a cada 20 itens se (i % 20 == 0) {session.flush (); // Clear Cached Contents session.clear (); }} session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}Nota: session.flush () significa limpar o cache de primeiro nível, mas iniciamos o cache de segundo nível novamente e, depois de salvar (), também o salva no cache de segundo nível, mas ainda há um transbordamento causado por cache excessivo. Portanto, neste caso, devemos desativar o cache secundário: session.setCachemode (Cachemode.ignore);
Cache de consulta: o cache de primeiro nível e o cache de cache de segundo nível de cache ambos os objetos da entidade de cache, mas às vezes esperamos obter certos atributos e não acessar frequentemente o banco de dados, mas obtê-lo no cache. Neste momento, podemos usar o cache de consulta. Além disso, os conjuntos de resultados de cache de consulta para objetos de entidade irão cache ID. O ciclo de vida do cache de consulta é alterado. Quando a tabela associada é modificada, o ciclo da declaração do cache de consulta termina, que não tem nada a ver com o ciclo de vida da sessão.
1. Modifique o arquivo hibernate.cfg.xml para ativar o cache de consulta. Se False for padrão, ele não está ativado. Deve ser definido da seguinte maneira:
<Propriedade name = "hibernate.cache.use_query_cache"> true </propriedade>
2. Deve ser ativado no programa, como:
query.setcacheable (true)
Método de teste:
public void testCache2 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.begIntransaction (); list nomes = session.CreateQuery ("selecione s.name de Student s") .SetcachEclee (true) .list (); para (int i = 0; nomes "). (String) names.get (i); system.out.println (nome);} session.gettransaction (). Commit ();} catch (Exceção e) {e.printStackTrace (); session.gettransaction (). Rollback ();} finalmente {Hibernateutils.clossession (session);} System.out.println ("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .list (); para (int i = 0; i <names.size (); i ++) {string name = (string) names.get (i); system.out.println (name);} session.gettransaction (). commit ();} catch (exceção e) {e.printstacktrace ();). {Hibernateutils.clossession (sessão);}}Nota: No código acima, desligamos o cache secundário, ligamos o cache de consulta e, em seguida, consultamos as propriedades normais. Execute o código de teste e podemos descobrir que, na primeira sessão, a primeira consulta emite uma declaração, depois fecha a sessão e, em seguida, consulte a segunda sessão. Descobrimos que a consulta na segunda sessão não emite uma declaração, o que significa que o cache de consulta não tem nada a ver com o ciclo de vida da sessão.
Configuração do cache de hibernate.cfg.xml:
<!-Defina a interface de implementação para especificar o cache secundário-> <propriedade name = "hibernate.cache.region.factory_class"> org.hibernate.cache.ehcacheregionFactory </oilter name = "net.sf.ehcache.configurationResourceName">/ehcache.xml </propriedade> <!-Defina o cache usando query-> <propriedades name = "hibernate.cache.use_Query_cache"> true </property> <!-carregar o arquivo/arquivo de objeto-> <mapping "> /> <Mapping Resource = "com /lixue /bean /student.hbm.xml" /> <!-O arquivo de mapeamento de recursos (ou seja, o arquivo de mapeamento de entidades) deve ser introduzido antes de configurar uma classe de entidade usando o cache de nível 2-> <classe-cache USAGE = "SOLLE" />
O exposto acima é todo o conteúdo deste artigo sobre a análise de código dos exemplos de mecanismo de cache do hibernato, espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!