C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
不使用配置文件
不使用配置文件方式
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost/users");
dataSource.setUser("root");
dataSource.setPassword("root");
conn = dataSource.getConnection();
String sql = "select * from user";
pstmt = conn.prepareStatement(sql);
c3p0配置文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<named-config name="mysql">
<!-- 配置数据库用户名 -->
<property name="user">root</property>
<!-- 配置数据库密码 -->
<property name="password">root</property>
<!-- 配置数据库链接地址 -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jsd1802db?characterEncoding=UTF-8&serverTimezone=Hongkong&useSSL=false&autoReconnect=true&failOverReadOnly=false</property>
<!-- jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8&serverTimezone=Hongkong&useSSL=false&autoReconnect=true&failOverReadOnly=false-->
<!-- 配置数据库驱动 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<!-- 数据库连接池一次性向数据库要多少个连接对象 -->
<property name="acquireIncrement">20</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">10</property>
<!-- 最小连接数 -->
<property name="minPoolSize">5</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">30</property>
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:0 -->
<property name="maxStatements">0</property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection">0</property>
<!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default:3 -->
<property name="numHelperThreads">3</property>
<!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">3</property>
<!-- 获取连接超时设置 默认是一直等待单位毫秒 -->
<property name="checkoutTimeout">1000</property>
<!--每多少秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">3</property>
<!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">10</property>
<!--配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待它close再断开。配置为0的时候则不会对连接的生存时间进行限制。 -->
<property name="maxIdleTimeExcessConnections">5</property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>
</named-config>
</c3p0-config>
连接数据库
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
// c3p0 设置数据库
public class JDBCUtil {
// 创建构建数据源对象DataSource
static ComboPooledDataSource dataSource = null;
static {
// 创建构建数据源对象DataSource
dataSource = new ComboPooledDataSource("mysql");
}
public static DataSource getDataSource() {
return dataSource;
}
/**
*
* @Title: getConn
* @Description: TODO(加载驱动并且获取连接对象)
* @param: @return
* @return: Connection 连接对象
* @throws
*/
public static Connection getConn() throws Exception {
System.out.println("数据库连接成功");
return dataSource.getConnection();
}
/**
*
* @Title: release
* @Description: TODO(关闭资源)
* @param: @param conn
* @param: @param stat
* @param: @param rs
* @return: void
* @throws
*/
public static void release(Connection conn, Statement stat, ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
if (stat != null) {
stat.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void test() {
try {
getConn();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用开源DBUtils 工具类 (简化CRUD的代码,连接,创建和获取需要JDBCUril)
* 增加,删除,修改
* queryRunner.update(sql);
//增加
//queryRunner.update("insert into account values (null , ? , ? )", "aa" ,1000);
//删除
//queryRunner.update("delete from account where id = ?", 5);
//更新
//queryRunner.update("update account set money = ? where id = ?", 10000000 , 6);
* 查询
* queryRunner.query(sql,rsh);
1. 直接new接口的匿名实现类
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
Account account = queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>(){
@Override
public Account handle(ResultSet rs) throws SQLException {
Account account = new Account();
while(rs.next()){
String name = rs.getString("name");
int money = rs.getInt("money");
account.setName(name);
account.setMoney(money);
}
return account;
}
}, 6);
System.out.println(account.toString());
2. 直接使用框架已经写好的实现类。
* 查询单个对象
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
//查询单个对象
Account account = queryRunner.query("select * from account where id = ?",
new BeanHandler<Account>(Account.class), 8);
* 查询多个对象
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
List<Account> list = queryRunner.query("select * from account ",
new BeanListHandler<Account>(Account.class));
###ResultSetHandler 常用的实现类
以下两个是使用频率最高的
BeanHandler, 查询到的单个数据封装成一个对象
BeanListHandler, 查询到的多个数据封装 成一个List<对象>
------------------------------------------
ArrayHandler, 查询到的单个数据封装成一个数组
ArrayListHandler, 查询到的多个数据封装成一个集合 ,集合里面的元素是数组。
MapHandler, 查询到的单个数据封装成一个map
MapListHandler,查询到的多个数据封装成一个集合 ,集合里面的元素是map。
自制DBUtils 工具类
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
*
* @ClassName: CommonCRUDUtil
* @Description:TODO(自制通用的增删改查工具类)
* @author: kiko
* @param <T>
* @date: 2018年6月12日 上午9:24:02
*
* @Copyright: 2018
*/
public class CommonCRUDUtil {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
/**
*
* @Title: update
* @Description: TODO(增删改操作)
* @param: @param sql 需要操作的sql语句
* @param: @param args 可变参数,有几个占位符 ,就写几个参数
* @return: void
* @throws
*/
public void update(String sql, Object... args) {
/**
* 测试增加代码
* update("insert into user values(null,?,?);", "123", "222");
* 测试删除代码
* update("DELETE FROM user WHERE `id` = ?; ", "3");
* 测试修改代码
* update("UPDATE user SET name = ? , password = ? WHERE id = ?;",
* "mvc", "构架", "2");
*/
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
// 以传入参数为准 循环替换sql语句的?号,出现问题 参数多少会导致错误
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps, rs);
}
}
public void update2(String sql, Object... args) {
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
// 通过参数的元数据 获取有几个?,占位符
ParameterMetaData metaData = ps.getParameterMetaData();
int count = metaData.getParameterCount();
for (int i = 0; i < count; i++) {
ps.setObject(i + 1, args[i]);
}
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps, rs);
}
}
public <T> T query(String sql, ResultSetHandler<T> handler, Object... args) {
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
// 通过参数的元数据 获取有几个?,占位符
ParameterMetaData metaData = ps.getParameterMetaData();
int count = metaData.getParameterCount();
for (int i = 0; i < count; i++) {
ps.setObject(i + 1, args[i]);
}
// 执行查询工作
rs = ps.executeQuery();
// 把结果集丢给调用者,封装数据,返回封装数据
T t = (T) handler.handle(rs);
return t;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.release(conn, ps, rs);
}
return null;
}
}