html5 微信网站,谁有马和人做的网站,用网站做的简历,崔各庄地区网站建设开始使用Hibernate的人们常见的问题之一就是性能#xff0c;如果您没有太多的Hibernate经验#xff0c;您会发现应用程序变慢的速度。 如果启用sql跟踪#xff0c;您将看到有多少查询被发送到数据库#xff0c;而这些查询几乎不需要Hibernate知识就可以避免。 在当前文章中… 开始使用Hibernate的人们常见的问题之一就是性能如果您没有太多的Hibernate经验您会发现应用程序变慢的速度。 如果启用sql跟踪您将看到有多少查询被发送到数据库而这些查询几乎不需要Hibernate知识就可以避免。 在当前文章中我将解释如何使用休眠查询缓存来避免应用程序和数据库之间的通信量。 Hibernate提供了两个缓存级别 一级缓存是会话缓存。 对象被缓存在当前会话中并且它们仅在会话关闭之前是活动的。 只要会话工厂处于活动状态第二级缓存就存在。 请记住在Hibernate情况下二级缓存不是对象树。 对象实例不被缓存而是存储属性值。 在简要介绍了一下Hibernate缓存之后让我知道这很简短让我们看一下什么是查询缓存以及如何与二级缓存相关联。 查询缓存负责将作为参数提供的查询和值的组合作为键进行缓存并将查询执行返回的对象的标识符列表作为值进行缓存。 注意使用查询缓存也需要二级缓存因为从缓存即标识符列表获取查询结果时 Hibernate将使用二级缓存的标识符加载对象。 概括起来作为一个概念性的模式给出下一个查询“ from country from countrynumber “第一次执行后 Hibernate缓存将包含下一个虚构值请注意number参数设置为1000 L2快取 [ id1{name Spain人口 1000...。} id2{name 德国人口 2000...} …。 QueryCache [{来自人口number的国家/地区1000}{id2}] 因此在开始使用查询缓存之前我们需要配置第二级缓存。 首先您必须确定要使用的缓存提供程序。 对于此示例选择了Ehcache 但请参阅Hibernate文档以获取所有支持的提供程序的完整列表。 要配置二级缓存请设置下一个休眠属性 hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider hibernate.cache.use_structured_entries true hibernate.cache.use_second_level_cache true 如果您使用注释方法请使用以下方法注释可缓存的实体 可缓存 Cache用法 CacheConcurrencyStrategy.NONSTRICT_READ_WRITE 可以看到在这种情况下缓存并发策略是NONSTRICT_READ_WRITE 但是根据缓存提供者的不同可以遵循其他策略例如TRANSACTIONALREAD_ONLY ………请查看Hibernate文档的缓存部分以选择最适合您需求的策略。 最后添加Ehcache依赖项 依赖性 groupId net.sf.ehcache / groupId artifactId ehcache-core / artifactId version 2.5.0 / version / dependency 依赖性 groupId org.hibernate / groupId artifactId hibernate-ehcache / artifactId version 3.6.0.Final / version / dependency 现在已配置了二级缓存但未配置查询缓存 无论如何我们离目标不远。 将hibernate.cache.use_query_cache属性设置为true 。 对于每个可缓存的查询我们必须在查询创建期间调用setCachable方法 List Country list session.createQuery“来自人口 1000的国家/地区”.setCacheabletrue.list; 为了使示例更实用我已经使用Spring Framework上传了完整的查询缓存示例。 为了清楚地了解查询缓存的工作原理我使用了一个在ensembl.org中托管的公共数据库。 Ensembl项目为脊椎动物和其他真核生物建立了基因组数据库并在线免费提供此信息。 在此示例中对dna表的查询被缓存。 首先进行Hibernate配置 Configuration
public class HibernateConfiguration {Value(#{dataSource})private DataSource dataSource;Beanpublic AnnotationSessionFactoryBean sessionFactoryBean() {Properties props new Properties();props.put(hibernate.dialect, EnhancedMySQL5HibernateDialect.class.getName());props.put(hibernate.format_sql, true);props.put(hibernate.show_sql, true);props.put(hibernate.cache.provider_class, org.hibernate.cache.EhCacheProvider);props.put(hibernate.cache.use_structured_entries, true);props.put(hibernate.cache.use_query_cache, true);props.put(hibernate.cache.use_second_level_cache, true);props.put(hibernate.hbm2ddl.auto, validate);AnnotationSessionFactoryBean bean new AnnotationSessionFactoryBean();bean.setAnnotatedClasses(new Class[]{Dna.class}); bean.setHibernateProperties(props);bean.setDataSource(this.dataSource);bean.setSchemaUpdate(true);return bean;}} 这是一个简单的Hibernate配置使用前面说明的属性来配置二级缓存。 实体类是代表DNA序列的实体。 Entity(namedna)
Cacheable
Cache(usage CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Dna {Idprivate int seq_region_id;private String sequence;public int getSeq_region_id() {return seq_region_id;}public void setSeq_region_id(int seq_region_id) {this.seq_region_id seq_region_id;}Columnpublic String getSequence() {return sequence;}public void setSequence(String sequence) {this.sequence sequence;}} 为了尝试查询缓存 我们将实现一项测试其中多次执行同一查询。 Autowired
private SessionFactory sessionFactory;Test
public void fiftyFirstDnaSequenceShouldBeReturnedAndCached() throws Exception {for (int i 0; i 5; i) {Session session sessionFactory.openSession();session.beginTransaction();Time elapsedTime new Time(findDnai);ListDna list session.createQuery(from dna).setFirstResult(0).setMaxResults(50).setCacheable(true).list();session.getTransaction().commit();session.close();elapsedTime.miliseconds(System.out);for (Dna dna : list) {System.out.println(dna);}}
} 我们可以看到我们正在返回前五十个dna序列如果执行它您将看到打印了从查询创建到提交事务之间的经过时间。 如您所料仅第一次迭代就需要大约5秒钟来获取所有数据而其他迭代只需数毫秒。 查询迭代之前的foreach行将通过控制台打印对象标识符。 如果仔细观察这些标识符将不会在所有执行期间重复。 这个事实只是向您显示Hibernate缓存不会保存对象而是保存属性值并且每次都会创建对象本身。 最后一点请记住默认情况下 Hibernate不缓存关联。 现在在编写查询之后考虑它是否将包含静态数据以及是否将经常执行。 在这种情况下 查询缓存是您的朋友可以使Hibernate应用程序运行得更快。 下载代码 参考来自JCG合作伙伴的 Hibernate缓存级别教程 在一个罐子统治他们所有博客的亚历克斯·索托。 翻译自: https://www.javacodegeeks.com/2012/02/hibernate-cache-levels-tutorial.html