spring学习-spring jdbc 连接池的配置(一)

来源:互联网 发布:sql语句select语法 编辑:程序博客网 时间:2024/05/16 10:29

数据连接池

1、 如果没有任何一个用户使用连接,那么那么应该维持一定数量的连接,等待用户使用。 
2、 如果连接已经满了,则必须打开新的连接,供更多用户使用。 
3、 如果一个服务器就只能有100个连接,那么如果有第101个人过来呢?应该等待其他用户释放连接 
4、 如果一个用户等待时间太长了,则应该告诉用户,操作是失败的。

下面对几个连接池进行示例配置:

在spring中,常使用数据库连接池来完成对数据库的连接配置,类似于线程池的定义,数据库连接池就是维护有一定数量数据库连接的一个缓冲池,一方面,能够即取即用,免去初始化的时间,另一方面,用完的数据连接会归还到连接池中,这样就免去了不必要的连接创建、销毁工作,提升了性能。当然,使用连接池,有一下几点是连接池配置所考虑到的,也属于配置连接池的优点,而这些也会我们后面的实例配置中体现:

在spring中,常用的连接池有:jdbc,dbcp,c3p0,JNDI4种,他们有不同的优缺点和适用场景。其中,spring框架推荐使用dbcp,hibernate框架推荐使用c3p0。经测试发现,c3p0与dbcp相比较,c3p0能够更好的支持高并发,但是在稳定性方面略逊于dpcp。

几个连接池的配置:

1.jdbc连接池配置

<bean id="dataSource"    class="org.springframework.jdbc.datasource.DriverManagerDataSource">    <property name="driverClassName" value="com.mysql.jdbc.Driver">    </property>    <property name="url" value="jdbc:mysql://localhost:3307/lucene?characterEncoding=UTF8" />    <property name="username" value="root"></property>    <property name="password" value="guo941102"></property></bean>
DriverManagerDataSource没有实现连接池化连接的机制,每次调用getConnection()获取新连接时,只是简单地创建一个新的连接。所以,一般这种方式常用于开发时测试,不用于生产。

2.c3p0连接池配置

<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:3307/lucene?characterEncoding=UTF8" />        <property name="user" value="root" />        <property name="password" value="guo941102" /></bean>


他有以下常用的属性:

属性                说明 默认值acquireIncrement当连接池中的连接用完时,C3P0一次性创建新连接的数目5acquireRetryAttempts定义在从数据库获取新连接失败后重复尝试获取的次数30checkoutTimeout当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒0initialPoolSize初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值3maxIdleTime最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃0maxPoolSize连接池中保留的最大连接数15numHelperThreads                  C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行3                                   

3.dbcp连接池配置实例(我的实例)

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"    destroy-method="close"><!--设置为close使Spring容器关闭同时数据源能够正常关闭,以免造成连接泄露  -->    <property name="driverClassName" value="com.mysql.jdbc.Driver" />    <property name="url" value="jdbc:mysql://localhost:3307/lucene?characterEncoding=UTF8" />    <property name="username" value="root" />    <property name="password" value="guo941102" />    <property name="defaultReadOnly" value="false" /><!-- 设置为只读状态,配置读写分离时,读库可以设置为true -->    <!-- 在连接池创建后,会初始化并维护一定数量的数据库安连接,当请求过多时,数据库会动态增加连接数,    当请求过少时,连接池会减少连接数至一个最小空闲值 -->    <property name="initialSize" value="5" /><!-- 在启动连接池初始创建的数据库连接,默认为0 -->    <property name="maxActive" value="15" /><!-- 设置数据库同一时间的最大活跃连接默认为8,负数表示不闲置 -->    <property name="maxIdle" value="10"/><!-- 在连接池空闲时的最大连接数,超过的会被释放,默认为8,负数表示不闲置 -->    <property name="minIdle" value="2" /><!-- 空闲时的最小连接数,低于这个数量会创建新连接,默认为0 -->    <property name="maxWait" value="10000" /><!-- 连接被用完时等待归还的最大等待时间,单位毫秒,超出时间抛异常,默认为无限等待 --></bean>
以上的的配置都是在开发中经常用到的

对于DBCP连接池:

默认连接池的使用无需导入其他的jar包,但使用DBCP连接池需要导入jar包:依赖包中org.apache.commons文件夹中:

(1)com.springsource.org.apache.commons.dbcp-1.4.jar

(2)com.springsource.org.apache.commons.pool-1.6.jar

4.实例

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"   xmlns:p="http://www.springframework.org/schema/p"  xsi:schemaLocation="           http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd            http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd            http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-context-3.0.xsd            http://www.springframework.org/schema/aop            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">  <!-- 使用XML Schema的p名称空间配置 -->    <bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3307/lucene?characterEncoding=UTF8"  p:username="root"    p:password="guo941102" >    </bean> <bean name="service" class="com.gym.dataService.Service"></bean>  </beans>
Service.java 
package com.gym.dataService;import java.io.IOException;import javax.sql.DataSource;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.jdbc.core.JdbcTemplate;public class Service {private ApplicationContext ctx;public Service() {super();}private DataSource getBasicDataSource() throws IOException {//建立连接池资源//BasicDataSource dataSource = new BasicDataSource();//    //读取配置信息//Properties prop = new Properties();//InputStream in = new BufferedInputStream (Service.class.getClassLoader().getResourceAsStream("config.properties"));//prop.load(in);//DriverClassName = prop.getProperty("driverclassname");//Url = prop.getProperty("url");//////进行配置//dataSource.setDriverClassName(DriverClassName);////设置数据库访问的URL//dataSource.setUrl(Url);////注意,在URL中已经设置过用户名和密码之后,就不需要再进行设置用户名和密码了,否则将会报错//////设置数据库访问的用户名////dataSource.setUsername(this.Username);//////设置数据库访问密码////dataSource.setPassword(this.Password); //////最大连接数量//dataSource.setMaxActive(150);  ////最小空闲连接//dataSource.setMinIdle(5);//// 最大空闲连接//dataSource.setMaxIdle(200);////初始化连接数量//dataSource.setInitialSize(30);////连接被泄露是是否打印//dataSource.setLogAbandoned(true); //// 是否自动回收超时连接//dataSource.setRemoveAbandoned(true); ////设置超时等待时间//dataSource.setRemoveAbandonedTimeout(10); ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");   DataSource dataSource= ctx.getBean("dataSource", DataSource.class);return dataSource;}public JdbcTemplate getJdbcTemplate() throws IOException {//加载sourceJdbcTemplate jdbcTemplate = new JdbcTemplate(getBasicDataSource());return jdbcTemplate;}}
//hints:刚开始,我使用注释处的方法配置的,后来发现web测试时,刷新两次就不能使用了,数据库拒绝连接,连接池创建多了。。。。,每次请求,实例化一次,肯定会炸,在JAVA application中运行还没事,移动到web上,忘记改了,就歇菜了

dataService.java

package com.gym.dataService;import java.io.IOException;import java.util.List;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.JdbcTemplate;import net.sf.json.JSONArray;import net.sf.json.JSONObject;public class dataService {public static Service service = new ClassPathXmlApplicationContext("/applicationContext.xml").getBean("service",Service.class);/** * 懒汉单例模式 * 获取JdbcTemplate * @return  * @throws IOException  */public static JdbcTemplate getTemplate() throws IOException {//if(service == null) {////注入实例//service = new Service();//}return service.getJdbcTemplate();}/** *  * @param sql  执行的sql语句 * @param args 不定项参数 * @return * @throws DataAccessException * @throws IOException */public static JSONArray toJSONArray(String sql, Object... args) throws DataAccessException, IOException {//if(service == null) {////注入实例//service = new Service();//}List list = service.getJdbcTemplate().queryForList(sql, args);return JSONArray.fromObject(list);}public static JSONObject toJSONObject(String sql, Object... args) throws DataAccessException, IOException {if(service == null) {//实例化service = new Service();}List list = service.getJdbcTemplate().queryForList(sql,args);if(list.size() == 0) {return new JSONObject();}return JSONObject.fromObject(list.get(0));}public static void main(String[] args) {try {JSONArray jsonArray = dataService.toJSONArray("select * from t_user where id = 2332 limit 10");System.out.println(jsonArray);for(int i=0;i<jsonArray.size();i++) {JSONObject json = jsonArray.getJSONObject(i);System.out.println("id:" + json.getString("id") + " username:" + json.getString("username") + " age:" + json.getString("age"));}} catch (DataAccessException e) {// TODO Auto-generated catch blockSystem.out.println(e.getMessage());} catch (IOException e) {// TODO Auto-generated catch blockSystem.out.println(e.getMessage());}System.out.println("-----------------------");try {JSONObject json = dataService.toJSONObject("select * from t_user where id = 1212 limit 1");System.out.println(json);System.out.println("id:" + json.optString("id",null) + " username:" + json.optString("username",null) + " age:" + json.optString("age",null));} catch (DataAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


此时还不会使用spring注解进行诸如,只能这样的先。