<?xml version="1.0" encoding="ISO-8859-1"?> <!-- the proxool configuration can be embedded within your own application's. Anything outside the "proxool" tag is ignored. --> <something-else-entirely> <proxool> <alias>snake</alias> <driver-url>jdbc:mysql://localhost:3306/snake?useUnicode=true&characterEncoding=gbk&autoReconnect=true</driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="java"/> <property name="password" value="mixed"/> </driver-properties> <maximum-connection-count>4</maximum-connection-count> <minimum-connection-count>2</minimum-connection-count> <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql> <statistics>15m,1h,1d</statistics> </proxool> </something-else-entirely>大概解析一下:
alias:自定义的一个名称,通过此名称与 hibernate 关联;
driver-url, driver-class:数据库连接串和 driver 的信息;
maximum-connection-count, minimum-connection-count:最大、最小连接数;
现在看看 hibernate 的配置文件
文件名为 hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- a SessionFactory instance listed as /jndi/name [name="java:hibernate/SessionFactory"] --> <session-factory> <!-- cache configuration --> <property name="hibernate.cache.provider_class">org.hibernate.cache.TreeCacheProvider</property> <!-- driver configuration --> <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> <!-- properties --> <property name="statement_cache.size">25</property> <property name="jdbc.fetch_size">50</property> <property name="jdbc.batch_size">50</property> <property name="show_sql">true</property> <!-- enable reconnect to database for a long time session --> <property name="connection.autoReconnect">true</property> <property name="connection.autoReconnectForPools">true</property> <property name="connection.is-connection-validation-required">true</property> <!-- Proxool Connection Pool --> <!-- Properties for external configuration of Proxool --> <property name="hibernate.proxool.pool_alias">snake</property> <property name="hibernate.proxool.existing_pool">false</property> <property name="hibernate.proxool.xml">proxool-snake.xml</property> <!-- mapping files --> <mapping resource="UserInfo.hbm.xml"/> <mapping resource="PlayerInfo.hbm.xml"/> <mapping resource="ReadInfo.hbm.xml"/> </session-factory> </hibernate-configuration>
大概解析一下:
hibernate.proxool.pool_alias:即 proxool 中设置的 alias;
hibernate.proxool.existing_pool:此值设为 false,当 hibernate 开始被调用时,就会初始化 proxool,进行数据库连接等操作,这样最省事;
hibernate.proxool.xml:proxool 配置文件的名字,此例中是 proxool-snake.xml
配置文件编辑完成后,需要放到 CLASSPATH 路径中,迟些我会另外再写文章介绍通过 build.xml 来实现。
接下来我介绍一种从网上学习的,使用 hibernate 的方法。就是通过 HibernateUtil 来取得 管理和取得 session。以下是代码
HibernateUtil.java
package mixed.snake.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static Log log = LogFactory.getLog(HibernateUtil.class); public static final ThreadLocal<Session> local = new ThreadLocal<Session>(); private static final SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (HibernateException e) { log.error("catch exception when configure hibernate: ", e); throw new RuntimeException("Configuration problem: " + e.getMessage(), e); } } public static Session currentSession() throws HibernateException { Session session = local.get(); if (session == null) { session = sessionFactory.openSession(); local.set(session); } return session; } public static void closeSession() throws HibernateException { Session session = local.get(); local.set(null); if (session != null) { session.close(); } } public static void lightup() { log.debug("HibernateUtil.lightup() : activating hibernate."); } }
hmm.. 怎么来使用这个 HibernateUtil 呢?
我的建议是:
对于 app 程序,
在初始化时 调用 HibernateUtil.lightup(); 以触发 hibernate 和 proxool 的初始化;
在程序内部,调用 HibernateUtil.currentSession() 取得 session 引用;
在程序释放时,调用 HibernateUtil.closeSession() 释放 session;
而对于 web 程序,以 struts 为例,可以这样使用,
写一个 PlugIn,在 init 时,调用 HibernateUtil.lightup();
同样,在应用中,调用 HibernateUtil.currentSession() 取得 session 引用;
最后是 session 的释放,一个技巧是通过 filter 来实现。
web.xml 中配置 hibernateFilter
<!-- hibernate filter configuration --> <filter> <filter-name>hibernateFilter</filter-name> <filter-class>mixed.filter.HibernateFilter</filter-class> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>HibernateFilter 代码
package mixed.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; import mixed.snake.util.HibernateUtil; public class HibernateFilter implements Filter { private static final Log log = LogFactory.getLog(HibernateFilter.class); public HibernateFilter() { super(); } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { chain.doFilter(request, response); } finally { try { HibernateUtil.closeSession(); } catch (HibernateException e) { log.error("catch exception:", e); } } } public void init(FilterConfig config) throws ServletException { } }以上就基本上实现了一种较为合理的 hibernate 应用方式了。