`

[转]笔记:Hibernate性能优化事项(持续更新)

    博客分类:
  • Java
 
阅读更多

1、针对Oracle数据库而言,Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数,一般设置为30、50、100。Oracle数据库的JDBC驱动默认的Fetch Size=15,设置Fetch Size设置为:30、50,性能会有明显提升,如果继续增大,超出100,性能提升不明显,反而会消耗内存。
  即在Hibernate配制文件中进行配制:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<!-- Create/update the database tables automatically when the JVM starts up
<prop key="hibernate.hbm2ddl.auto">update</prop> -->
<!-- Turn batching off for better error messages under PostgreSQL
<prop key="hibernate.jdbc.batch_size">100</prop> -->
<prop key="hibernate.jdbc.fetch_size">50</prop>
</props>
</property>
Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。
  2、如果是超大的系统,建议生成htm文件。加快页面提升速度。
  3、不要把所有的责任推在hibernate上,对代码进行重构,减少对数据库的操作,尽量避免在数据库查询时使用in操作,以及避免递归查询操作,代码质量、系统设计的合理性决定系统性能的高低。
  4、 对大数据量查询时,慎用list()或者iterator()返回查询结果,
  (1). 使用List()返回结果时,Hibernate会所有查询结果初始化为持久化对象,结果集较大时,会占用很多的处理时间。
  (2). 而使用iterator()返回结果时,在每次调用iterator.next()返回对象并使用对象时,Hibernate才调用查询将对应的对象初始化,对于大数据量时,每调用一次查询都会花费较多的时间。当结果集较大,但是含有较大量相同的数据,或者结果集不是全部都会使用时,使用iterator()才有优势。
  5、在一对多、多对一的关系中,使用延迟加载机制,会使不少的对象在使用时方会初始化,这样可使得节省内存空间以及减少数据库的负荷,而且若PO中的集合没有被使用时,就可减少互数据库的交互从而减少处理时间。
  6、对含有关联的PO(持久化对象)时,若default-cascade="all"或者 “save-update”,新增PO时,请注意对PO中的集合的赋值操作,因为有可能使得多执行一次update操作。
  7、 对于大数据量新增、修改、删除操作或者是对大数据量的查询,与数据库的交互次数是决定处理时间的最重要因素,减少交互的次数是提升效率的最好途径,所以在开发过程中,请将show_sql设置为true,深入了解Hibernate的处理过程,尝试不同的方式,可以使得效率提升。尽可能对每个页面的显示,对数据库的操作减少到100----150条以内。越少越好。

 

 

以上是在进行struts+hibernate+spring进行项目开发中,对hibernate性能优化的几点心得。  

 

  •  

    在一个拥有单独业务层的应用中,业务层必须在返回之前,为web层“准备”好其所需的数据集合。这就意味着 业务层应该载入所有表现层/web层所需的数据,并将这些已实例化完毕的数据返回。通常,应用程序应该 为web层所需的每个集合调用Hibernate.initialize() (这个调用必须发生咱session关闭之前); 或者使用带有FETCH 从句,或FetchMode.JOIN 的Hibernate查询, 事先取得所有的数据集合。如果你在应用中使用了Command模式,代替Session Facade , 那么这项任务将会变得简单的多。

  •  

    你也可以通过merge() lock() 方法,在访问未实例化的集合(或代理)之前, 为先前载入的对象绑定一个新的Session 。 显然,Hibernate将不会,也不应该自动完成这些任务,因为这将引入一个特殊的事务语义。

     

    有时候,你并不需要完全实例化整个大的集合,仅需要了解它的部分信息(例如其大小)、或者集合的部分内容。

    你可以使用集合过滤器得到其集合的大小,而不必实例化整个集合:

    ( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()

    这里的createFilter() 方法也可以被用来有效的抓取集合的部分内容,而无需实例化整个集合:

    s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();

     

    20.1.5. 使用批量抓取(Using batch fetching)

     

    Hibernate可以充分有效的使用批量抓取,也就是说,如果仅一个访问代理(或集合),那么Hibernate将不载入其他未实例化的代理。 批量抓取是延迟查询抓取的优化方案,你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。

    类/实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你在一个Session 中载入了25个 Cat 实例,每个Cat 实例都拥有一个引用成员owner , 其指向Person ,而Person 类是代理,同时lazy="true" 。 如果你必须遍历整个cats集合,对每个元素调用getOwner() 方法,Hibernate将会默认的执行25次SELECT 查询, 得到其owner的代理对象。这时,你可以通过在映射文件的Person 属性,显式声明batch-size ,改变其行为:

    <class name="Person" batch-size="10">...</class>

    随之,Hibernate将只需要执行三次查询,分别为10、10、 5。

    你也可以在集合级别定义批量抓取。例如,如果每个Person 都拥有一个延迟载入的Cats 集合, 现在,Sesssion 中载入了10个person对象,遍历person集合将会引起10次SELECT 查询, 每次查询都会调用getCats() 方法。如果你在Person 的映射定义部分,允许对cats 批量抓取, 那么,Hibernate将可以预先抓取整个集合。请看例子:

    <class name="Person"> <set name="cats" batch-size="3"> ... </set></class>

    如果整个的batch-size 是3(笔误?),那么Hibernate将会分四次执行SELECT 查询, 按照3、3、3、1的大小分别载入数据。这里的每次载入的数据量还具体依赖于当前Session 中未实例化集合的个数。

    如果你的模型中有嵌套的树状结构,例如典型的帐单-原料结构(bill-of- materials pattern),集合的批量抓取是非常有用的。 (尽管在更多情况下对树进行读取时,嵌套集合(nested set)或原料路径(materialized path)(××) 是更好的解决方法。)

     

    20.1.6. 使用子查询抓取(Using subselect fetching)

     

    假若一个延迟集合或单值代理需要抓取,Hibernate会使用一个subselect重新运行原来的查询,一次性读入所有的实例。这和批量抓取的实现方法是一样的,不会有破碎的加载。

     

    20.1.7. 使用延迟属性抓取(Using lazy property fetching)

     

    Hibernate3对单独的属性支持延迟抓取,这项优化技术也被称为组抓取 (fetch groups)。 请注意,该技术更多的属于市场特性。在实际应用中,优化行读取比优化列读取更重要。但是,仅载入类的部分属性在某些特定情况下会有用,例如在原有表中拥有 几百列数据、数据模型无法改动的情况下。

    可以在映射文件中对特定的属性设置lazy ,定义该属性为延迟载入。

    <class name="Document"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="50"/> <property name="summary" not-null="true" length="200" lazy="true"/> <property name="text" not-null="true" length="2000" lazy="true"/></class>

    属性的延迟载入要求在其代码构建时加入二进制指示指令(bytecode instrumentation),如果你的持久类代码中未含有这些指令, Hibernate将会忽略这些属性的延迟设置,仍然将其直接载入。

    你可以在Ant的Task中,进行如下定义,对持久类代码加入“二进制指令。”

    <target name="instrument" depends="compile"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask"> <classpath path="${jar.path}"/> <classpath path="${classes.dir}"/> <classpath refid="lib.class.path"/> </taskdef> <instrument verbose="true"> <fileset dir="${testclasses.dir}/org/hibernate/auction/model"> <include name="*.class"/> </fileset> </instrument></target>

    还有一种可以优化的方法,它使用HQL或条件查询的投影(projection)特性,可以避免读取非必要的列, 这一点至少对只读事务是非常有用的。它无需在代码构建时“二进制指令”处理,因此是一个更加值得选择的解决方法。

    有时你需要在HQL中通过抓取所有属性 ,强行抓取所有内容。

     

    20.2. 二级缓存(The Second Level Cache)

     

    Hibernate的Session 在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或JVM级别(SessionFactory级别 )的缓存。 你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。

    默认情况下,Hibernate使用EHCache进行JVM级别的缓存(目前,Hibernate已经废弃了对JCS的支持,未来版本中将会去掉它)。 你可以通过设置hibernate.cache.provider_class 属性,指定其他的缓存策略, 该缓存策略必须实现org.hibernate.cache.CacheProvider 接口。

  •  

    表 20.1. 缓存策略提供商(Cache Providers)

    Cache Provider class Type Cluster Safe Query Cache Supported
    Hashtable (not intended for production use) org.hibernate.cache.HashtableCacheProvider memory yes
    EHCache org.hibernate.cache.EhCacheProvider memory, disk yes
    OSCache org.hibernate.cache.OSCacheProvider memory, disk yes
    SwarmCache org.hibernate.cache.SwarmCacheProvider clustered (ip multicast) yes (clustered invalidation)
    JBoss TreeCache org.hibernate.cache.TreeCacheProvider clustered (ip multicast), transactional yes (replication) yes (clock sync req.)

     

    20.2.1. 缓存映射(Cache mappings)

    类或者集合映射的“<cache> 元素”可以有下列形式:

    <cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/>

     

    (1)

     

    usage 说明了缓存的策略: transactional read-write nonstrict-read-write read-only

    另外(首选?), 你可以在hibernate.cfg.xml中指定<class-cache> <collection-cache> 元素。

    这里的usage 属性指明了缓存并发策略(cache concurrency strategy)。

     

    20.2.2. 策略:只读缓存(Strategy: read only)

     

    如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。

    <class name="eg.Immutable" mutable="false"> <cache usage="read-only"/> ....</class>

     

    20.2.3. 策略:读/写缓存(Strategy: read/write)

     

    如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在JTA环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_class 属性的值, 通过它,Hibernate才能知道该应用程序中JTA的TransactionManager 的具体策略。 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate内置的缓存策略并不支持锁定功能。

    <class name="eg.Cat" .... > <cache usage="read-write"/> .... <set name="kittens" ... > <cache usage="read-write"/> .... </set></class>

     

    20.2.4. 策略:非严格读/写缓存(Strategy: nonstrict read/write)

     

    如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存 策略。如果在JTA环境中使用该策略, 你必须为其指定hibernate.transaction.manager_lookup_class 属性的值, 在其它环境中,你必须保证在Session.close() 、或Session.disconnect() 调用前, 整个事务已经结束。

     

    20.2.5. 策略:事务缓存(transactional)

     

    Hibernate的事务缓存 策略提供了全事务的缓存支持, 例如对JBoss TreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定 为其hibernate.transaction.manager_lookup_class 属性。

    没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。

     

    表 20.2. 各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support)

    Cache read-only nonstrict-read-write read-write transactional
    Hashtable (not intended for production use) yes yes yes
    EHCache yes yes yes
    OSCache yes yes yes
    SwarmCache yes yes
    JBoss TreeCache yes yes

     

    20.3. 管理缓存(Managing the caches)

     

    无论何时,当你给save() update() saveOrUpdate() 方法传递一个对象时,或使用load() get() list() iterate() scroll() 方法获得一个对象时, 该对象都将被加入到Session 的内部缓存中。

    当随后flush()方法被调用时,对象的状态会和数据库取得同步。 如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用evict() 方法,从一级缓存中去掉这些对象及其集合。

    ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result setwhile ( cats.next() ) { Cat cat = (Cat) cats.get(0); doSomethingWithACat(cat); sess.evict(cat);}

    Session还提供了一个contains() 方法,用来判断某个实例是否处于当前session的缓存中。

    如若要把所有的对象从session缓存中彻底清除,则需要调用Session.clear()

    对于二级缓存来说,在SessionFactory 中定义了许多方法, 清除缓存中实例、整个类、集合实例或者整个集合。

    sessionFactory.evict(Cat.class, catId); //evict a particular CatsessionFactory.evict(Cat.class); //evict all CatssessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittenssessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections

    CacheMode 参数用于控制具体的Session如何与二级缓存进行交互。

     

    •  

      CacheMode.NORMAL - 从二级缓存中读、写数据。

    •  

      CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。

    •  

      CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。

    •  

      CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts 的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。

     

    如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。

    Map cacheEntries = sessionFactory.getStatistics() .getSecondLevelCacheStatistics(regionName) .getEntries();

    此时,你必须手工打开统计选项。可选的,你可以让Hibernate更人工可读的方式维护缓存内容。

    hibernate.generate_statistics truehibernate.cache.use_structured_entries true

     

    20.4. 查询缓存(The Query Cache)

     

    查询的结果集也可以被缓存。只有当经常使用同样的参数进行查询时,这才会有些用处。 要使用查询缓存,首先你必须打开它:

    hibernate.cache.use_query_cache true

    该设置将会创建两个缓存区域 - 一个用于保存查询结果集(org.hibernate.cache.StandardQueryCache ); 另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache )。 请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。 所以查询缓存通常会和二级缓存一起使用。

    绝大多数的查询并不能从查询缓存中受益,所以Hibernate默认是不进行查询缓存的。如若需要进行缓存,请调用 Query.setCacheable(true) 方法。这个调用会让查询在执行过程中时先从缓存中查找结果, 并将自己的结果集放到缓存中去。

    如果你要对查询缓存的失效政策进行精确的控制,你必须调用Query.setCacheRegion() 方法, 为每个查询指定其命名的缓存区域。

    List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger") .setEntity("blogger", blogger) .setMaxResults(15) .setCacheable(true) .setCacheRegion("frontpages") .list();

    如果查询需要强行刷新其查询缓存区域,那么你应该调用Query.setCacheMode(CacheMode.REFRESH) 方法。 这对在其他进程中修改底层数据(例如,不通过Hibernate修改数据),或对那些需要选择性更新特定查询结果集的情况特别有用。 这是对SessionFactory.evictQueries() 的更为有效的替代方案,同样可以清除查询缓存区域。

     

    20.5. 理解集合性能(Understanding Collection performance)

     

    前面我们已经对集合进行了足够的讨论。本段中,我们将着重讲述集合在运行时的事宜。

     

    20.5.1. 分类(Taxonomy)

     

    Hibernate定义了三种基本类型的集合:

     

    •  

      值数据集合

    •  

      一对多关联

    •  

      多对多关联

     

    这个分类是区分了不同的表和外键关系类型,但是它没有告诉我们关系模型的所有内容。 要完全理解他们的关系结构和性能特点,我们必须同时考虑“用于Hibernate更新或删除集合行数据的主键的结构”。 因此得到了如下的分类:

     

    •  

      有序集合类

    •  

      集合(sets)

    •  

      包(bags)

     

    所有的有序集合类(maps, lists, arrays)都拥有一个由<key> <index> 组成的主键。 这种情况下集合类的更新是非常高效的——主键已经被有效的索引,因此当Hibernate试图更新或删除一行时,可以迅速找到该行数据。

    集合(sets)的主键由<key> 和其他元素字段构成。 对于有些元素类型来说,这很低效,特别是组合元素或者大文本、大二进制字段; 数据库可能无法有效的对复杂的主键进行索引。 另一方面,对于一对多、多对多关联,特别是合成的标识符来说,集合也可以达到同样的高效性能。( 附注:如果你希望SchemaExport 为你的<set> 创建主键, 你必须把所有的字段都声明为not-null="true" 。)

    <idbag> 映射定义了代理键,因此它总是可以很高效的被更新。事实上, <idbag> 拥有着最好的性能表现。

    Bag是最差的。因为bag允许重复的元素值,也没有索引字段,因此不可能定义主键。 Hibernate无法判断出重复的行。当这种集合被更改时,Hibernate将会先完整地移除 (通过一个(in a single DELETE ))整个集合,然后再重新创建整个集合。 因此Bag是非常低效的。

    请注意:对于一对多关联来说,“主键”很可能并不是数据库表的物理主键。 但就算在此情况下,上面的分类仍然是有用的。(它仍然反映了Hibernate在集合的各数据行中是如何进行“定位”的。)

     

    20.5.2. Lists, maps 和sets用于更新效率最高

     

    根据我们上面的讨论,显然有序集合类型和大多数set都可以在增加、删除、修改元素中拥有最好的性能。

    可论证的是对于多对多关联、值数据集合而言,有序集合类比集合(set)有一个好处。因为Set 的内在结构, 如果“改变”了一个元素,Hibernate并不会更新(UPDATE) 这一行。 对于Set 来说,只有在插入(INSERT) 删除(DELETE) 操作时“改变”才有效。再次强调:这段讨论对“一对多关联”并不适用。

    注意到数组无法延迟载入,我们可以得出结论,list, map和idbags是最高效的(非反向)集合类型,set则紧随其后。 在Hibernate中,set应该时最通用的集合类型,这时因为“set”的语义在关系模型中是最自然的。

    但是,在设计良好的Hibernate领域模型中,我们通常可以看到更多的集合事实上是带有inverse="true" 的一对多的关联。对于这些关联,更新操作将会在多对一的这一端进行处理。因此对于此类情况,无需考虑其集合的更新性能。

     

    20.5.3. Bag和list是反向集合类中效率最高的

     

    在把bag扔进水沟之前,你必须了解,在一种情况下,bag的性能(包括list)要比set高得多: 对于指明了inverse="true" 的集合类(比如说,标准的双向的一对多关联), 我们可以在未初始化(fetch)包元素的情况下直接向bag或list添加新元素! 这是因为Collection.add() )或者Collection.addAll() 方法 对bag或者List总是返回true(这点与与Set不同)。因此对于下面的相同代码来说,速度会快得多。

    Parent p = (Parent) sess.load(Parent.class, id); Child c = new Child(); c.setParent(p); p.getChildren().add(c); //no need to fetch the collection! sess.flush();

     

    20.5.4. 一次性删除(One shot delete)

     

    偶尔的,逐个删除集合类中的元素是相当低效的。Hibernate并没那么笨, 如果你想要把整个集合都删除(比如说调用list.clear()),Hibernate只需要一个DELETE就搞定了。

    假设我们在一个长度为20的集合类中新增加了一个元素,然后再删除两个。 Hibernate会安排一条INSERT 语句和两条DELETE 语句(除非集合类是一个bag)。 这当然是显而易见的。

    但是,假设我们删除了18个数据,只剩下2个,然后新增3个。则有两种处理方式:

     

    •  

      逐一的删除这18个数据,再新增三个;

    •  

      删除整个集合类(只用一句DELETE语句),然后增加5个数据。

     

    Hibernate还没那么聪明,知道第二种选择可能会比较快。 (也许让Hibernate不这么聪明也是好事,否则可能会引发意外的“数据库触发器”之类的问题。)

    幸运的是,你可以强制使用第二种策略。你需要取消原来的整个集合类(解除其引用), 然后再返回一个新的实例化的集合类,只包含需要的元素。有些时候这是非常有用的。

    显然,一次性删除并不适用于被映射为inverse="true" 的集合。

     

    20.6. 监测性能(Monitoring performance)

     

    没有监测和性能参数而进行优化是毫无意义的。Hibernate为其内部操作提供了一系列的示意图,因此可以从 每个SessionFactory 抓取其统计数据。

     

    20.6.1. 监测SessionFactory

     

    你可以有两种方式访问SessionFactory 的数据记录,第一种就是自己直接调用 sessionFactory.getStatistics() 方法读取、显示统计 数据。

    此外,如果你打开StatisticsService MBean选项,那么Hibernate则可以使用JMX技术 发布其数据记录。你可以让应用中所有的SessionFactory 同时共享一个MBean,也可以每个 SessionFactory分配一个MBean。下面的代码即是其演示代码:

    // MBean service registration for a specific SessionFactoryHashtable tb = new Hashtable();tb.put("type", "statistics");tb.put("sessionFactory", "myFinancialApp");ObjectName on = new ObjectName("hibernate", tb); // MBean object nameStatisticsService stats = new StatisticsService(); // MBean implementationstats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactoryserver.registerMBean(stats, on); // Register the Mbean on the server

    // MBean service registration for all SessionFactory'sHashtable tb = new Hashtable();tb.put("type", "statistics");tb.put("sessionFactory", "all");ObjectName on = new ObjectName("hibernate", tb); // MBean object nameStatisticsService stats = new StatisticsService(); // MBean implementationserver.registerMBean(stats, on); // Register the MBean on the server

    TODO:仍需要说明的是:在第一个例子中,我们直接得到和使用MBean;而在第二个例子中,在使用MBean之前 我们则需要给出SessionFactory的JNDI名,使用hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name") 得到SessionFactory,然后将MBean保存于其中。

    你可以通过以下方法打开或关闭SessionFactory 的监测功能:

     

    •  

      在配置期间,将hibernate.generate_statistics 设置为true false

     

     

    •  

      在运行期间,则可以可以通过sf.getStatistics().setStatisticsEnabled(true) hibernateStatsBean.setStatisticsEnabled(true)

     

    你也可以在程序中调用clear() 方法重置统计数据,调用logSummary() 在日志中记录(info级别)其总结。

     

    20.6.2. 数据记录(Metrics)

     

    Hibernate提供了一系列数据记录,其记录的内容包括从最基本的信息到与具体场景的特殊信息。所有的测量值都可以由 Statistics 接口进行访问,主要分为三类:

     

    •  

      使用Session 的普通数据记录,例如打开的Session的个数、取得的JDBC的连接数等;

    •  

      实体、集合、查询、缓存等内容的统一数据记录

    •  

      和具体实体、集合、查询、缓存相关的详细数据记录

     

    例如:你可以检查缓存的命中成功次数,缓存的命中失败次数,实体、集合和查询的使用概率,查询的平均时间等。请注意 Java中时间的近似精度是毫秒。Hibernate的数据精度和具体的JVM有关,在有些平台上其精度甚至只能精确到10秒。

    你可以直接使用getter方法得到全局数据记录(例如,和具体的实体、集合、缓存区无关的数据),你也可以在具体查询中通过标记实体名、 或HQL、SQL语句得到某实体的数据记录。请参考Statistics EntityStatistics CollectionStatistics SecondLevelCacheStatistics 、 和QueryStatistics 的API文档以抓取更多信息。下面的代码则是个简单的例子:

    Statistics stats = HibernateUtil.sessionFactory.getStatistics();double queryCacheHitCount = stats.getQueryCacheHitCount();double queryCacheMissCount = stats.getQueryCacheMissCount();double queryCacheHitRatio = queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);log.info("Query Hit ratio:" + queryCacheHitRatio);EntityStatistics entityStats = stats.getEntityStatistics( Cat.class.getName() );long changes = entityStats.getInsertCount() + entityStats.getUpdateCount() + entityStats.getDeleteCount();log.info(Cat.class.getName() + " changed " + changes + "times" );

    如果你想得到所有实体、集合、查询和缓存区的数据,你可以通过以下方法获得实体、集合、查询和缓存区列表: getQueries() getEntityNames() getCollectionRoleNames() getSecondLevelCacheRegionNames()

     

     

     

     

     

    分享到:
    评论

    相关推荐

      Hibernate练习笔记

      【Hibernate实践探索】 在深入探讨Hibernate这一强大的Java对象关系映射(ORM)框架之前,我们需要先理解ORM的...在实际开发中,结合最佳实践和持续优化,可以充分发挥Hibernate的优势,提高项目的可维护性和性能。

      java全套培训笔记

      笔记可能包含JUnit的使用,它是Java的单元测试框架,以及如何使用IDE(如Eclipse、IntelliJ IDEA)进行调试和性能优化。 最后,笔记可能还会介绍如何进行有效的代码管理和版本控制,如Git的使用,以及持续集成/持续...

      软件测试学习笔记

      ### 软件测试学习笔记知识点详解 #### 一、软件测试基础知识 1. **软件测试定义** - **理解**:软件测试是通过执行软件产品来评估其质量的过程。 - **目的**:确保软件产品能够满足用户的需求并达到预定的质量...

      基于JAVA的云笔记系统设计与实现.zip

      综上所述,《基于JAVA的云笔记系统设计与实现》涵盖了Java Web开发的多个关键领域,从系统架构到安全策略,再到用户体验和性能优化,提供了全面的实践指导。通过学习和实践,开发者可以掌握构建云服务的核心技能。

      java笔记 资料收藏大师

      8. **最佳实践**:了解并遵循Java编码规范,掌握单元测试(JUnit)、持续集成(Jenkins)、版本控制(Git)等开发工具的使用,以及代码重构和性能优化技巧,这些都是提升开发效率和软件质量的关键。 以上就是标题...

      Java后端学习笔记代码Java后端学习笔记代码

      12. **性能优化**: 分析和优化Java应用性能,如内存管理、JVM调优、数据库查询优化等。 13. **并发编程**: 掌握Java并发库,如ExecutorService、Future、锁机制,理解线程池和并发容器的使用。 14. **分布式系统**...

      SSH整合笔记

      - 考虑性能优化,避免一次性加载过多数据。 #### 七、内存分析 - 监控应用程序的内存使用情况; - 使用工具如 JVisualVM 进行堆内存分析; - 识别并解决内存泄漏等问题。 #### 八、软件生命周期 - 了解软件从...

      Java架构面试专题(含答案)和学习笔记.rar

      9. **性能调优**:CPU、内存、磁盘I/O等方面的性能分析和优化技巧,以及使用工具如JProfiler、VisualVM等。 10. **代码质量与测试**:单元测试、集成测试、持续集成/持续部署(CI/CD)、代码质量管理(SonarQube)...

      JAVA框架核心技术笔记

      总结,本笔记涵盖了Java框架的核心技术和相关实践,包括Spring、Hibernate、MyBatis等常用框架的使用,JavaEE基础知识,RESTful API设计,以及测试、集成、安全和性能优化等多个方面,全面提升了Java开发者的技术...

      J2EE框架学习笔记.

      Hibernate是流行的JPA实现,提供了更强大的功能和性能优化。 7. JSF(JavaServer Faces):JSF是一种用于构建用户界面的MVC(模型-视图-控制器)框架,简化了组件化UI开发,提供了丰富的UI组件库。 8. Spring框架...

      基于JAVA开发的购买笔记本电商app源码

      11. **性能与可扩展性**:为应对高并发访问,应用可能采用负载均衡、缓存技术(如Redis)、数据库分库分表等手段,确保系统的高性能和可扩展性。 12. **测试与部署**:单元测试、集成测试确保代码质量,而持续集成/...

      JavaEE就业班笔记

      深入理解JVM(Java虚拟机)的工作原理,包括内存管理、垃圾回收机制以及性能优化策略,也是提升开发效率的重要环节。 在实际项目中,学习者还需要掌握版本控制工具,如Git,以及持续集成/持续部署(CI/CD)工具,如...

      webwork学习笔记

      - 从技术角度比较Struts 1.1与WebWork 2的区别,如架构设计、性能优化等方面。 - **项目资源**: - 官方网站、社区论坛、文档资料等。 - **参考资料**: - 官方文档。 - 开发指南。 - 第三方文章和博客。

      Java架构学习笔记Xmind图.zip

      Java架构学习笔记Xmind...这些知识点只是Java架构学习的一部分,实际的Xmind图可能还涵盖了其他主题,如设计模式、性能优化、分布式事务处理等。通过深入学习和实践,开发者可以不断提升自己在Java架构领域的专业能力。

      03_关于互联网Java工程师面试突击训练课程的几点说明.zip

      10. **持续学习与行业动态**:关注最新的Java版本更新、开源项目、技术趋势,如Java 8及以后的新特性,以及云原生、容器化等。 通过这个训练课程,学员应能系统性地复习和提升以上各方面的知识,以应对互联网公司的...

      java重点和难点笔记.zip

      8. **调试和优化**:理解如何有效地使用IDE(集成开发环境)的调试工具,以及如何优化代码性能(例如,内存管理、算法优化)是成为优秀Java开发者不可或缺的部分。 9. **文档和规范**:阅读和理解官方API文档,了解...

      javaEE商城第二天笔记.pdf

      【JavaEE商城系统开发核心...以上是JavaEE商城系统开发的一些核心知识点,实际开发中还会涉及到更多细节,如异常处理、日志记录、性能优化等。对于每一个环节,深入理解和熟练掌握都能提升整个系统的质量和用户体验。

    Global site tag (gtag.js) - Google Analytics