Java使用c3p0建立MySQL数据库连接池

25 篇文章 0 订阅

序言

 数据库连接的设计上有三种思路,第一是对于每一个用户都创建一个连接,等到该用户访问完就将数据库连接释放。第二种是设置一个静态连接变量,所有用户都使用该连接。第三种就是使用数据库连接池。

在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

 JDBC数据库连接池的实现必须实现javax.sql.DataSource接口,其中DataSource称为数据源,该数据源的实现有以下三种: 
  C3p0:C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能。目前使用它的开源项目有hibernatespring等。c3p0有自动回收空闲连接功能。 
  DBCP:是Apache上的一个 Java连接池项目,也是 tomcat使用的连接池组件。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。dbcp没有自动的去回收空闲连接的功能。 
  Proxool:Proxool是一种Java数据库连接池技术,是sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。 
  对比结果: 
  性能dbcp<=c3p0<proxool 
  稳定性dbcp>=c3p0>proxool

实现

首先需要导入3个先关的Java,工程具体见图片,

下面来写c3p0的配置xml文件

#jdbc基本信息  
driverClass=com.mysql.jdbc.Driver 
jdbcUrl=jdbc:mysql://127.0.0.1:3306/pool
user=root
password=root 
  
#c3p0连接池信息  
c3p0.minPoolSize=3  
c3p0.maxPoolSize=25  
  
#当连接池中的连接耗尽的时候c3p0一次同时获取的连接数  
c3p0.acquireIncrement=3  
#定义在从数据库获取新连接失败后重复尝试的次数  
c3p0.acquireRetryAttempts=60  
#两次连接中间隔时间,单位毫秒  
c3p0.acquireRetryDelay=1000  
#连接关闭时默认将所有未提交的操作回滚  
c3p0.autoCommitOnClose=false  
#当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒  
c3p0.checkoutTimeout=3000  
#每120秒检查所有连接池中的空闲连接。Default: 0  
c3p0.idleConnectionTestPeriod=120  
#最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0  
c3p0.maxIdleTime=600  
#如果设为true那么在取得连接的同时将校验连接的有效性。Default: false  
c3p0.testConnectionOnCheckin=true  
#c3p0将建一张名为c3p0TestTable的空表,并使用其自带的查询语句进行测试。  
#jdbc.automaticTestTable = c3p0TestTable  

然后写一个c3p0的util工具

package com.test.util;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


import com.mchange.v2.c3p0.ComboPooledDataSource;


public class C3P0Util {
static ComboPooledDataSource cpds = null;
static {
// 这里有个优点,写好配置文件,想换数据库,简单
// cpds = new ComboPooledDataSource("oracle");//这是oracle数据库
cpds = new ComboPooledDataSource("mysql");// 这是mysql数据库
}


/**
* 获得数据库连接

* @return Connection
*/
public static Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}


/**
* 数据库关闭操作

* @param conn
* @param st
* @param pst
* @param rs
*/
public static void close(Connection conn, PreparedStatement pst, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}


if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}


/**
* 测试DBUtil类

* @param args
*/
public static void main(String[] args) {
Connection conn = getConnection();
System.out.println(conn.getClass().getName());
close(conn, null, null);
}
}


然后写一个统一的sql操作帮助类

package com.test.util;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;


public class SQLHelper {
private Connection conn = null;
   private PreparedStatement ps = null;
   private ResultSet rs = null;
 
   /**
    * 数据查询
    * @param sql语句
    * @return 返回结果集List<Object>
    */
   public List<Object> query(String sql) {
       if(sql.equals("") || sql == null){
           return null;
       }
       List<Object> list = new ArrayList<Object>();
       try {
           conn = C3P0Util.getConnection();
           ps = conn.prepareStatement(sql);
           rs = ps.executeQuery();
           ResultSetMetaData rsmd = rs.getMetaData();
           // 可以得到有多少列
           int columnNum = rsmd.getColumnCount();
           // 将数据封装到list中
           while (rs.next()) {
               Object[] objects = new Object[columnNum];
               for (int i = 0; i < objects.length; i++) {
                   objects[i] = rs.getObject(i + 1);
               }
               list.add(objects);
           }
       } catch (Exception e) {
           // TODO: handle exception
           e.printStackTrace();
       }
       return list;
   }
 
   /**
    * 插入、修改数据操作
    * @param sql语句
    * @return boolean 成功返回true,失败返回false
    */
   public boolean update(String sql) {
       boolean b = false;
       if(sql.equals("") || sql == null){
           return b;
       }
       try {
           conn = C3P0Util.getConnection();
           ps = conn.prepareStatement(sql);
           int i = ps.executeUpdate();
           if (i == 1) {
               b = true;
           }
       } catch (Exception e) {
           // TODO: handle exception
           e.printStackTrace();
       }
       return b;
   }
 
}


最后写一个测试类

package com.test.test;


import java.util.ArrayList;
import java.util.List;


import com.test.bean.User;
import com.test.util.SQLHelper;


public class Test {
private SQLHelper sqlHelper = new SQLHelper();
    
    /**
     * 测试query
     */
    public void testQuery(){
        String sql = "select * from pool where id = 1";
        List list = sqlHelper.query(sql);
        List<User> lists = new ArrayList<User>();
        
        for (int i = 0; i < list.size(); i++) {
            Object object[] = (Object[]) list.get(i);
            User user=new User();
            user.setId(Integer.parseInt(object[0].toString()));
            System.out.println(object[0].toString());
            user.setUserName(object[1].toString());
            System.out.println(object[1].toString());
            lists.add(user);
        }
        
    }
    /**
     * 测试insert、update、delete
     */
    /*public void testInsertOrUpdate(){
        String sql = "delete from crh2_station where id = 1";
        boolean b = sqlHelper.update(sql);
        if(b){//b为true则操作成功
            System.out.println("操作成功");
        }else{//b为false则操作失败
            System.out.println("操作失败");
        }
    }*/
    
    public static void main(String[] args){
    Test test=new Test();
    test.testQuery();
    }
   
}


当然,中间需要一个bean类

package com.test.bean;


public class User {
private Integer id;
    private String userName;
    private String passWord;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
    
}


  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值