没有监测和性能参数而进行优化是毫无意义的。Hibernate为其内部操作提供了一系列的示意图,因此可以从 每个SessionFactory
抓取其统计数据。
你可以有两种方式访问SessionFactory
的数据记录,第一种就是自己直接调用 sessionFactory.getStatistics()
方法读取、显示统计
数据。
此外,如果你打开StatisticsService
MBean选项,那么Hibernate则可以使用JMX技术 发布其数据记录。你可以让应用中所有的SessionFactory
同时共享一个MBean,也可以每个 SessionFactory分配一个MBean。下面的代码即是其演示代码:
// MBean service registration for a specific SessionFactory Hashtable tb = new Hashtable(); tb.put("type", "statistics"); tb.put("sessionFactory", "myFinancialApp"); ObjectName on = new ObjectName("hibernate", tb); // MBean object name StatisticsService stats = new StatisticsService(); // MBean implementation stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory server.registerMBean(stats, on); // Register the Mbean on the server
// MBean service registration for all SessionFactory's Hashtable tb = new Hashtable(); tb.put("type", "statistics"); tb.put("sessionFactory", "all"); ObjectName on = new ObjectName("hibernate", tb); // MBean object name StatisticsService stats = new StatisticsService(); // MBean implementation server.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)
Statistics can be reset programmatically using the clear()
method. A summary can be sent to a logger (info level) using the logSummary()
method.
Hibernate提供了一系列数据记录,其记录的内容包括从最基本的信息到与具体场景的特殊信息。所有的测量值都可以由 Statistics
接口进行访问,主要分为三类:
使用Session
的普通数据记录,例如打开的Session的个数、取得的JDBC的连接数等;
实体、集合、查询、缓存等内容的统一数据记录
和具体实体、集合、查询、缓存相关的详细数据记录
For example, you can check the cache hit, miss, and put ratio of entities, collections and queries, and the average time a query needs. Beware that the number of milliseconds is subject to approximation in Java. Hibernate is tied to the JVM precision, on some platforms this might even only be accurate to 10 seconds.
你可以直接使用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()
。