使用SSM框架搭建JavaWeb,使用Junit测试时遇到CannotGetJdbcConnetionException
背景:
在使用Spring、SpringMVC、Mybatis、Maven、c3p0,junit4.12搭建一个简单的增删改查JavaWeb项目;
依赖导入完备,写好基本的实体类,DAO,和mybatis的配置文件、mapper文件都编写好之后,在使用junit做数据库表做查询时测试时发生以下错误:
错误如下:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
具体如下图:
一开始我的数据源和参数文件配置如下:
jdbc.properties文件:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306ckill?useUnicode=true&characterEncoding=utf-8 username=JavaEE password=JavaEE
spring配置文件中的c3p0配置:
1 <!-- 2、配置数据库连接池 --> 2 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 3 <property name="driverClass" value="${driver}" /> 4 <property name="jdbcUrl" value="${url}" /> 5 <property name="user" value="${username}" /> 6 <property name="password" value="${password}" /> 7 8 <property name="maxPoolSize" value="30" /> 9 <property name="minPoolSize" value="10" /> 10 <!--关闭 关闭连接时自动的提交--> 11 <property name="autoCommitOnClose" value="false" /> 12 <!-- 连接失败时,重试次数 --> 13 <property name="acquireIncrement" value="2" /> 14 </bean>
第一次修改:
按照spring官方文档的c3p0配置,如图:
发现properties文件中的key都是以 jdbc. 开头,在xml文件中引用也用jdbc.开头,改之! 但并没有效果,依旧报同样的异常;
第二次修改:
将线程池最大线程数调大,并加上初始线程数以及超时自动关闭线程,则变成:
1 <property name="maxPoolSize" value="50" /> 2 <property name="minPoolSize" value="10" /> 3 4 <propery name="initialPoolSize" value="3" /> 5 <propery name="jdbc.checkoutTimeout“ value="2000" /> 6 <!--关闭 关闭连接时自动的提交--> 7 <property name="autoCommitOnClose" value="false" /> 8 <!-- 连接失败时,重试次数 --> 9 <property name="acquireIncrement" value="2" />
还是无效,报同样的错误!
第三次修改:
会不会是配置文件的某些单词拼写错了? 检查一遍,报错依旧!
符号用错了? 检查一遍,报错依旧!
spring配置文件不能载入properties文件? 不是,未能载入是报not found的错误!
参数空格打多了? 改了,报错依旧!!
第四次修改:
该不会数据库有问题?
那尝试一下写多一个测试方法,用代码的方式直接连接数据库:
1 Class.forName("com.mysql.jdbc.Driver"); 2 String url="jdbc:mysql://localhost:3306ckill?useUnicode=true&characterEncoding=utf-8"; 3 String username="JavaEE"; 4 String password="JavaEE"; 5 Connection con=DriverManager.getConnection(url, username, password); 6 Statement stmt = con.createStatement(); 7 String sql="select seckill_id,name,number,start_time,end_time,create_time from seckill where seckill_id=1000"; 8 ResultSet result=stmt.executeQuery(sql); 9 while(result.next()) { 10 System.out.println(result.getString("name")+" "); 11 System.out.println(result.getString("phone")+" "); 12 }
成功了!eclipse的junit出现小绿条!!那就说明报错的原因与数据库连接无关,那原因就是c3p0的配置问题了!
然后我把c3p0配置中的以下两句去掉之后,测试就通过了!
<propery name="jdbc.checkoutTimeout“ value="2000" />
<property name="autoCommitOnClose" value="false" />
最终配置如下:
jdbc.properties文件(以jdbc.为前缀,去掉多余的空格):
1 jdbc.driver=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306ckill?useUnicode=true&characterEncoding=utf-8 3 jdbc.username=JavaEE 4 jdbc.password=JavaEE
spring bean配置文件中的c3p0:
1 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 2 <property name="driverClass" value="${jdbc.driver}" /> 3 <property name="jdbcUrl" value="${jdbc.url}" /> 4 <property name="user" value="${jdbc.username}" /> 5 <property name="password" value="${jdbc.password}" /> 6 7 <property name="maxPoolSize" value="20" /> 8 <property name="minPoolSize" value="5" /> 9 <property name="initialPoolSize" value="3" /> 10 <!-- 连接失败时,重试次数 --> 11 <property name="acquireIncrement" value="2" /> 12 </bean>