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.boPooledDataSource;// c3p0 设置数据库public class JDBCUtil {// 创建构建数据源对象DataSourcestatic ComboPooledDataSource dataSource = null;static {// 创建构建数据源对象DataSourcedataSource = 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();}}@Testpublic void test() {try {getConn();} catch (Exception e) {// TODO Auto-generated catch blocke.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>(){@Overridepublic 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: 6月12日 上午9:24:02* * @Copyright: */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 blocke.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 blocke.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 blocke.printStackTrace();} finally {JDBCUtil.release(conn, ps, rs);}return null;}}