干货|数据库连接池

Posted 牛客NOIP竞赛学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干货|数据库连接池相关的知识,希望对你有一定的参考价值。

是新朋友吗?记得先点蓝字关注我哦~

为什么要有数据库连接池?


数据库的连接对象创建工作,比较消耗性能。


什么是数据库连接池?


一开始在内存中开辟一块空间(集合),一开始先往池子里面放置多个连接对象。后面需要连接的话,直接从池子里面去。不要去自己创建连接了。使用完毕,要记得归还连接。

编写自己的数据库连接池


代码实现(要实现DataSource接口):

package com.itheima.jdbc.util;import java.io.PrintWriter;import java.sql.Connection;import java.sql.SQLException;import java.sql.SQLFeatureNotSupportedException;import java.util.ArrayList;import java.util.List;import java.util.logging.Logger;import javax.sql.DataSource;public class MyDataSource implements DataSource{ List<Connection> list = new ArrayList<Connection>(); public MyDataSource() { System.err.println("对象创建成功了..."); for(int i=0;i<10;i++) { Connection conn = JDBCUtil.getConn(); list.add(conn); } } @Override public Connection getConnection() throws SQLException { //来拿如果连接池是空的 if(list.size()==0) { for(int i=0;i<10;i++) { Connection conn = JDBCUtil.getConn(); list.add(conn); } } //拿走了,就获取第一个,并移除第一个。 Connection con = list.remove(0); System.err.println("拿到了..."); return con; } public void addBack(Connection con) { System.err.println("归还了..."); list.add(con); }/*------------------下面的没用到------------------*/ @Override public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { // TODO Auto-generated method stub } @Override public void setLoginTimeout(int seconds) throws SQLException { // TODO Auto-generated method stub } @Override public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method stub return null; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return false; } @Override public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; }}


测试代码

package com.itheima.jdbc.util;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class dataBases { public static void main(String[] args) { // TODO Auto-generated method stub Connection conn = null; PreparedStatement ps = null; MyDataSource mydatasource = new MyDataSource(); try { conn = mydatasource.getConnection(); String sql = "insert into bank values(null,'wangwu',1000)"; ps = (PreparedStatement) conn.prepareStatement(sql); ps.executeUpdate(); } catch (SQLException e) { try { ps.close(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // TODO Auto-generated catch block e.printStackTrace(); }finally { mydatasource.addBack(conn); } }}

开源连接池


DBCP

database connection pool


不使用配置文件,首先导入以下两个包

干货|数据库连接池


package com.java1995;import com.itheima.jdbc.util.JDBCUtil;import org.apache.commons.dbcp.BasicDataSource;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class DBCPDemo { public static void main(String[] args){ Connection conn = null; PreparedStatement ps = null; try { /*1、构建数据源对象*/ BasicDataSource dataSource = new BasicDataSource(); //配置数据库信息 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost/soft03"); dataSource.setUsername("root"); dataSource.setPassword("w19980315"); /*2、得到连接对象*/ conn = dataSource.getConnection(); String sql = "insert into bank values(null,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, "zhaoliu"); ps.setInt(2, 1000); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.release(conn, ps); } }}

使用配置文件


还是导入那两个包,另外在配置文件里写上数据库信息:

干货|数据库连接池


代码如下:

package com.java1995;import com.itheima.jdbc.util.JDBCUtil;import org.apache.commons.dbcp.BasicDataSourceFactory;import javax.sql.DataSource;import java.io.FileInputStream;import java.io.InputStream;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.Properties;public class DBCPDemo02 { public static void main(String [] args) { Connection conn = null; PreparedStatement ps = null; BasicDataSourceFactory factory = new BasicDataSourceFactory(); Properties properties = new Properties(); try { InputStream is = new FileInputStream("src/dbcpconfig.properties"); properties.load(is); DataSource dataSource = factory.createDataSource(properties); conn = dataSource.getConnection(); String sql = "insert into bank values(null,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, "aobama"); ps.setInt(2, 400); ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtil.release(conn, ps); } }}


C3P0

不使用配置文件,首先导入C3P0的jar包

干货|数据库连接池

package com.java1995;import com.itheima.jdbc.util.JDBCUtil;import com.mchange.v2.c3p0.ComboPooledDataSource;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class C3P0Demo { public static void main(String[] args){ Connection con = null; PreparedStatement ps = null; try { /*1、创建datasource*/ ComboPooledDataSource dataSource = new ComboPooledDataSource(); /*2、设置数据库连接信息*/ dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost/soft03"); dataSource.setUser("root"); dataSource.setPassword("w19980315"); /*3、得到连接对象*/ con = dataSource.getConnection(); String sql = "insert into bank values(null , ? ,?)"; ps = con.prepareStatement(sql); ps.setString(1, "luhan"); ps.setInt(2, 100); ps.executeUpdate(); } catch (PropertyVetoException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.release(con, ps); } }}


使用配置文件


C3P0说明文档

干货|数据库连接池

package com.java1995;import com.itheima.jdbc.util.JDBCUtil;import com.mchange.v2.c3p0.ComboPooledDataSource;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class C3P0Demo { public static void main(String[] args){ Connection con = null; PreparedStatement ps = null; try { ComboPooledDataSource dataSource = new ComboPooledDataSource(); con = dataSource.getConnection(); String sql = "insert into bank values(null , ? ,?)"; ps = con.prepareStatement(sql); ps.setString(1, "wangbo"); ps.setInt(2, 1001111); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.release(con, ps); } }}


DBUtils


增删改


//dbutils 只是帮我们简化了CRUD 的代码, 但是连接的创建以及获取工作。不在他的考虑范围QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());//增加//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);
//查询//直接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());


直接使用框架已经写好的实现类

查询单个对象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。





更多有趣的内容

请长按


长按二维码关注



戳阅读原文与作者交流

以上是关于干货|数据库连接池的主要内容,如果未能解决你的问题,请参考以下文章

干货php Redis连接池

#yyds干货盘点# .NET Core 中对象池(Object Pool)的使用

Spring Boot Redis Cluster 实战干货

C# SQLConnection 池

那些好用数据库连接池JVM调优实战开源项目分享

手写数据库连接池实战