您的位置:首页 > 编程语言 > Java开发

Spring+Hibernate的连接池配置(c3p0,proxool)

2012-03-20 17:54 525 查看
1、proxool

首先需要导入jar包proxool-0.9.1.jar和proxool-cglib.jar;

创建proxool.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<something-else-entirely>

<proxool>

<alias>proxoolPool</alias>

<driver-url>jdbc:oracle:thin:@192.168.1.153:1521:ORCL</driver-url>

<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>

<driver-properties>

<property name="user" value="username" />

<property name="password" value="password" />

</driver-properties>

<house-keeping-sleep-time>90000</house-keeping-sleep-time>

<prototype-count>15</prototype-count>

<maximum-connection-count>20</maximum-connection-count>

<minimum-connection-count>5</minimum-connection-count>

<house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>

</proxool>

</something-else-entirely>

然后在web.xml中加载该xml文件

......

<servlet>

<servlet-name>proxoolInitialServlet</servlet-name>

<servlet-class>

org.logicalcobwebs.proxool.configuration.ServletConfigurator

</servlet-class>

<init-param>

<param-name>xmlFile</param-name>

<param-value>/WEB-INF/classes/proxool.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet>

<servlet-name>proxool</servlet-name>

<servlet-class>

org.logicalcobwebs.proxool.admin.servlet.AdminServlet

</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>proxool</servlet-name>

<url-pattern>/Admin/proxool</url-pattern>

</servlet-mapping>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

classpath:applicationContext.xml,

classpath:applicationContext-*.xml

</param-value>

</context-param>

<servlet>

<servlet-name>contextConfigLocation</servlet-name>

<servlet-class>

org.springframework.web.context.ContextLoaderServlet

</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet>

......

接下来在spring中配置

<bean id="dataSource"

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName">

<value>org.logicalcobwebs.proxool.ProxoolDriver</value>

</property>

<property name="url">

<value>proxool.proxoolPool</value>

</property>

</bean>

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

<property name="dataSource">

<ref bean="dataSource" />

</property>

<property name="configLocation"

value="classpath:hibernate.cfg.xml">

</property>

</bean>

在hibernate.cfg.xml中就不要配置连接源了,只是写一些mapping就可以了

2、c3p0

首先导入jar包c3p0-0.9.1.2.jar和c3p0-oracle-thin-extras-0.9.1.2.jar;

这个只需要配置spring的配置文件就好,配置内容如下:

<bean id="dataSource"

class="com.mchange.v2.c3p0.ComboPooledDataSource"

destroy-method="close">

<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>

<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.1.153:1521:ORCL"></property>

<property name="user" value="username"></property>

<property name="password" value="password"></property>

<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 1 -->

<property name="acquireIncrement"

value="1">

</property>

<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->

<property name="initialPoolSize"

value="3">

</property>

<!--最大空闲时间,30秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

<property name="maxIdleTime" value="30"></property>

<!--连接池中保留的最大连接数。Default: 15 -->

<property name="maxPoolSize" value="15"></property>

<!--连接池中保留的最小连接数。Default: 3 -->

<property name="minPoolSize" value="3"></property>

<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->

<property name="acquireRetryDelay" value="1000"></property>

<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->

<property name="acquireRetryAttempts" value="60"></property>

<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效

保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试

获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->

<property name="breakAfterAcquireFailure" value="false"></property>

</bean>

<!--Hibernate SessionFatory-->

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="configLocations">

<list>

<value>classpath:hibernate.cfg.xml</value>

</list>

</property>

<property name="configurationClass"

value="org.hibernate.cfg.AnnotationConfiguration" />

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">

org.hibernate.dialect.Oracle9Dialect

</prop>

<prop key="hibernate.show_sql">

false

</prop>

<prop key="hibernate.max_fetch_depth">

3

</prop>

<!-- 配置C3P0ConnectionProvider-->

<prop key="hibernate.connection.provider_class">

org.hibernate.connection.C3P0ConnectionProvider

</prop>

</props>

</property>

</bean>

配置结束,完活

3、需要注意的事项:

。如果dao继承HibernateDaoSupport,一定要用getHibernateTemplate(),不要使用getSession(),因为getSession()会得到原始的session,session的关闭以及事务完全不受spring控制了,我想既然是整合还是由spring来控制session会比较好,有些方法getHibernateTemplate()里面没有非要用session怎么办,方法如下:

public int queryByUserCount(final Users user) {

log.debug("finding Users count instance by example");

try {

int result = (Integer) getHibernateTemplate().execute(

new HibernateCallback() {

public Object doInHibernate(Session arg0)

throws HibernateException, SQLException {

Example example = Example.create(user)

.excludeZeroes().ignoreCase().enableLike(); // use

// like

// for

// string

// comparisons

Criteria crit = arg0.createCriteria(Users.class)

.add(example).addOrder(Order.asc("userid"));

int totalPage = ((Number) crit.setProjection(

Projections.rowCount()).uniqueResult())

.intValue();

return totalPage;

}

});

return result;

} catch (RuntimeException re) {

log.error("find by example failed", re);

throw re;

}

}

。如果在service类或者它的父类中定义了私有ApplicationContext的私有变量,千万不要通过new的形式来获得,否则spring在加载service类的时候会给每个ApplicationContext创建一个连接,也就是连接数和service的个数是一样的,即使在变量前面加上static final,也会在启动tomcat的时候创建一个连接,在启动tomcat的时候,本来在web.xml中已经加载过spring的配置文件,会创建一个连接,这样就会有两个连接,如果你的连接池初始连接数是3,就会创建3*2=6的连接数,如果变量前面没加static
final,启动tomcat创建的连接数就是service类的个数*3+1,这样很容易达到数据库允许连接的上限导致无法获得连接,这显然不是我们想要的,解决方法就是一、避免在service中定义ApplicationContext的私有变量,这有点不合人情;二、从web.xml中获取ApplicationContext,方法如下:

首先新建一个类SJBInit.java,内容如下:

public class SJBInit {

/**

* 系统应用spring环境

*/

private static ApplicationContext ctx;

/**

* 单实例对象

*/

private static SJBInit instance = null;

Vector temp = new Vector(50);

/**

* 构造函数

*/

public SJBInit() {

if (instance == null){

instance = this;

}

}

/**

* 获得单实例对象

*

* @return

*/

public static SJBInit getInstance() {

if (instance == null)

new SJBInit();

return instance;

}

/**

* 初始化Spring组件

*/

public void init(Properties props) throws Exception {

loadContextXML(props);

}

/**

* 加载spring对象

*

* @param props

*/

private void loadContextXML(Properties props) throws Exception{

String path ="";

/*LogFactory.getInstance().logRun(RunPriority.INFORMATIONAL,

LogConstants.sysLogConstants.INT_SPRING_START,

null

);*/

try {

ServletContext servletContext = (ServletContext) props

.get("APP_CONTEXT");

if (servletContext != null)

ctx = WebApplicationContextUtils

.getRequiredWebApplicationContext(servletContext);

}

catch (Exception e) {

e.printStackTrace();

}

if ((ctx == null) || (ctx.getBeanDefinitionNames().length == 0)) {

}

}

/**

* 得到spring的所有配置文件

*

* @param path

* @return

*/

private void setConfigFiles(String path) {

File file = new File(path);

if (file.isDirectory()) {

File[] files = file.listFiles();

for (int index = 0; index < files.length; index++) {

String filePath = files[index].getPath();

if (filePath.endsWith(".xml")) {

this.temp.add(filePath);

}

}

}

}

/**

* 得到一个spring的配置对象

*

* @param name

* @return

*/

public Object getBean(String name) {

if (ctx == null)

return null;

else

return ctx.getBean(name);

}

/**

* 获取单个信息

*

* @param key

* @param object

* @param request

* @return

*/

public static String getMessage(String key, Object[] object, Locale locale) {

return ctx.getMessage(key, object, locale);

}

}

然后创建InitServlet.java,内容如下:

public class InitServlet extends HttpServlet{

static final long serialVersionUID = -1111516993124229949L;

/**

* 启动对象实例

*/

private SJBInit sjbinit = SJBInit.getInstance();

/**

* servlet初始化

*/

public void init(ServletConfig config) throws ServletException {

super.init(config);

Properties props = new Properties();

props.put("APP_CONTEXT", config.getServletContext());

// 文件路径

String prefix = getServletContext().getRealPath("/");

// web应用路径

props.put("APP_PATH", prefix);

try {

sjbinit.init(props);

}catch(Exception e){

}

}

}

然后在web.xml中配置

...

<servlet>

<description>System init when start</description>

<display-name>InitServlet</display-name>

<servlet-name>InitServlet</servlet-name>

<servlet-class>com.fone.platform.core.InitServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

classpath:applicationContext.xml,

classpath:applicationContext-*.xml

</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

.....

然后再创建类SJBUtil.java,内容如下:

public class SJBUtil {

/**

* sjb管理类实例

*/

private static SJBInit sjb = SJBInit.getInstance();

/**

* 得到一个系统配置 bean

*

* @param name bean的配置名称

* @return 如果系统没有加载返回 null

*/

public static Object getBean(String name) {

return sjb.getBean(name);

}

}

然后在service类中通过SJBUtil.getBean("...");就可以获得spring中的dao类了

public UsersDAO getUsersDAO() {

return (UsersDAO) SJBUtil.getBean(SJBNameConstants.DAO_USERS_BEAN_NAME);

}

这个问题结束。

。如果连接数太过,报出heap内存溢出的异常,可以进行如下配置:

如果启动tomcat的时候出现heap溢出,需要修改tomcat目录下bin目录下的两个文件:

1、catalina.bat:在第一行中添加set JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

2、catalina.sh:在第一行中添加JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

如果运行tomcat还有heap内存溢出,就在tomcat中配置jdk参数-Xms512m -Xmx512m

tomcat->config->Tomcat 5.x->JDK,添加jdk之后,在下面添加参数-Xms512m -Xmx512m
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: