java调用存储过程 从spring中获取数据库连接

最近做的项目中有个统计分析的功能,里面需要多个表的数据汇总后作计算进行排名,就需要写很多SQL,于是乎想到用存储过程,调用一次后可以返回所有供计算使用的数据,中间遇到种种问题,现总结一二:
首先是java代码调用存储过程部分:
public Map<String, Object> rankInfo(Map<String, Object> rankMap,String start,String end, String userId,String officeId, String rankType,String timeType){
try {
//排名前十的用户答题详情
List<RecodeRank> topTenUsers = new ArrayList<RecodeRank>();
//当前用户在部门、当前用户在单位、当前用户在系统、用户部门在系统、用户单位在系统答题总数、答题正确数
Connection conn = GetDBConnection.getDbConnection();//获取数据库连接
try {
CallableStatement cs = conn.prepareCall("{call getUserTrain(?,?,?,?)}");//调用存储过程
//1-4为存储过程中输入参数赋值
cs.setString(1, start);
cs.setString(2, end);
cs.setString(3, officeId);
cs.setString(4, rankType);
boolean rs = cs.execute();//执行存储过程,执行过程中创建表,将汇总数据存放在表中
try{
//从存储过程创建的表中取出统计结果,利用java代码取出前十名和当前用户的排名信息(此处省略) 
............
 rankMap.put("topTenUsers", topTenUsers);
}finally{
cs.close();
}
}finally {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return rankMap;
}
期间遇到最大的问题就是获取数据源链接的了,在解决问题之前我找到两种方法获取数据源链接(即代码中Connection conn = GetDBConnection.getDbConnection();),如下为方法一:
package ..............;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class GetDBConnection {


public static Connection getDbConnection(){
//dbConnection.xml文件为单独创建文件,配置连接数据库
ApplicationContext ctx = new ClassPathXmlApplicationContext("dbConnection.xml");
//dataSource配置文件中bean的ID
DataSource dataSource = ctx.getBean("dataSource",DataSource.class);
try {
Connection conn = dataSource.getConnection();
return conn;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
dbConnection.xml文件介绍:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">


<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/数据库名称?useUnicode=true&amp;characterEncoding=UTF-8" />
<property name="user" value="数据库用户名" />
<property name="password" value="数据库密码" />

<property name="maxPoolSize" value="50"></property>
<property name="minPoolSize" value="10"></property><!--注意这里 -->
<property name="initialPoolSize" value="10"></property><!-- 注意这里-->

<property name="maxIdleTime" value="25000"></property>
<property name="acquireIncrement" value="1"></property>
<property name="acquireRetryAttempts" value="30"></property>
<property name="acquireRetryDelay" value="1000"></property>
<property name="testConnectionOnCheckin" value="true"></property>
<property name="idleConnectionTestPeriod" value="18000"></property>
<property name="checkoutTimeout" value="5000"></property>
<property name="automaticTestTable" value="t_c3p0"></property>
</bean>


</beans>
作好这一切,存储过程调用成功了,数据也返回了,但是。。。。。。但是当我多调用几次这个方法,就异常了:Too many connection  .......,好恐怖,我做了什么?
经过俩小时的奋战,终于找到问题了,看到上面的initialPoolSize、minPoolSize没有,就是那里,配置的10呢,调用一次该方法,数据库连接就增加十个,很快就超过了连接上限!!
然而,当我把initialPoolSize、minPoolSize的值都改成1,或者把这俩属性都去掉,虽然调用一次存储过程数据库连接增加的没有十个之多了,


反倒变成了调用一次增加三个或者四个连接,这是什么问题呢?本人也百思不得其解,也么有百度出个结果,望知道的看官告知一二


于是,又想到,每次调用都去创建连接是不是太浪费了,工程在启动的时候应该初始化的有连接,为什么不直接去取已创建的连接呢?于是有了方法二,如下:
创建一个工具类,在Spring的配置文件中配置该工具类,应用程序启动时会使用ApplicationContextAware让Spring容器传递自己生成的ApplicationContext给我们,然后我们把这个ApplicationContext
设置成一个类的 静态变量,这样我们就随时都可以在老的代码里得到Application的对象了(虽说这是我百度出来的方法,但是可行啊!!!)。
<bean id="SpringApplicationContext" class="com.XXX.XXX.handler.ApplicationContextHelper"></bean>
工具类ApplicationContextHelper.java:
package .............;


import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;


public class ApplicationContextHelper implements ApplicationContextAware{


private static ApplicationContext appCtx;

/**
* 把APplicationContext对象inject到当前类中作为一个静态成员变量
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appCtx = applicationContext;
}

/**
* 获取applicationContext
* @return
*/
public static ApplicationContext getApplicationContext(){
return appCtx;
}

/**
* 帮助我们快速得到一个bean
* @param beanName
* @return
*/
public static Object getBean(String beanName){
return appCtx.getBean(beanName);
}


}
接下来调用该工具类重的方法咯:
package .............;


import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import com.examstack.portal.security.handler.ApplicationContextHelper;


public class GetDBConnection {


private static Connection conn;
public static Connection getDbConnection() throws SQLException{
//在这里调用工具类获取数据源
DataSource dataSource = (DataSource) ApplicationContextHelper.getBean("dataSource");
conn = DataSourceUtils.getConnection(dataSource);
return conn;
}

}
java调用存储过程的代码还是原来的代码,赶紧运行起来看看吧..........!!!


亏得倒腾了一两天........,搞定,收工。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值