<?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 应用方式了。