关于数据库连接池:

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

2 一开始在内存中开辟一块空间,往池子里放置多个连接对象,需要连接的时候从连接池里面调用,

使用完毕归还连接,确保连接对象能够循环利用。解决jdbc中连接部分的工作

自定义数据库连接池:

/**
*
* 这是一个数据库连接池
* 1 一开始先往池子里放10个连接
* 2 通过getConnection获取连接
* 3 用完之后用addback归还连接
* 4 扩容
*
* 问题:
* 1 sun公司针对数据库连接池定义的一套规范
* 需要额外记住addBack的方法
* 2 需要做成单例
* 3 无法面向接口编程,因为接口里面没有定义addBack方法
*/
public class MyDataSource implements DataSource{ List<Connection> list = new ArrayList<>();
public MyDataSource(){
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 conn = list.remove(0);
return conn;
}
//归还
public void addBack(Connection conn){
list.add(conn);
} @Override

解决自定义数据库连接池出现的问题

修改接口的close方法,Connection调用close,归还对象,而非关闭连接

如何扩展?

1. 修改源码

2. 继承,必须得知道这个接口的具体实现是谁

3. 使用装饰者模式

4. 动态代理

开源连接池:DBCP,C3P0

DBCP:Apache开发

DBCP开发的两种方式:

public class DBCPDemo {

  static String driverClassName  = "com.mysql.jdbc.Driver";
//jdbc主协议,mysql子协议,所以类名倒着写driverClassName为com.mysql,url为jdbc协议下mysql
//主协议:子协议://本地:数据库
static String url = "jdbc:mysql://localhost/bank";
static String username = "root";
static String password = "fungsumyuet"; @Test
//手动设置的方式
public void testDBCP01(){ Connection conn = null;
PreparedStatement ps = null;
try {
//构建数据源对象
BasicDataSource dataSource = new BasicDataSource();
//数据库连接参数
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
conn = dataSource.getConnection();
String sql = "insert into account values(null,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "bushi");
ps.setInt(2, 1000);
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
} @Test
//配置文件的方式,因为是Java工程而非web工程,所以可以用IO流FileInputStream加载文件,web工程用类加载形式
public void testDBCP02(){
Connection conn = null;
PreparedStatement ps = null;
try {
BasicDataSourceFactory factory = new BasicDataSourceFactory();
Properties properties = new Properties();
InputStream is = new FileInputStream("src//dbcpconfig.properties");
properties.load(is);;
DataSource dataSource = factory.createDataSource(properties); conn = dataSource.getConnection();
String sql = "insert into account values(null,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "liangchaowei");
ps.setInt(2, 1000);
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
}

C3P0(重点掌握):

public class C3P0Demo01 {

    @Test
//c3p0代码方式
public void testC3P0(){
//1 .创建dataSource
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = null;
PreparedStatement ps = null;
try {
//设置参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
dataSource.setUser("root");
dataSource.setPassword("fungsumyuet");
conn = dataSource.getConnection();
String sql = "insert into account values(null,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "zhourunfa");
ps.setInt(2,1000);
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
} @Test
//C3P0配置文件方式
public void testC3P02(){ Connection conn = null;
PreparedStatement ps = null;
try {
//1 .创建dataSource,源码里面类加载形式加载配置文件
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置参数
conn = dataSource.getConnection();
String sql = "insert into account values(null,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "wuqilong");
ps.setInt(2,1000);
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
}

DBUtils:联合连接池,简化CRUD操作

1.导包,引入配置文件

2.创建连接池对象,dataSource

3.将连接池对象传进QueryRunner()

4.处理业务实现功能

public class TestDBUtils {

   @Test
public void demo01() throws SQLException{
//C3P0连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//dbUtils简化CRUD代码
QueryRunner queryRunner = new QueryRunner(dataSource);
//增加
// queryRunner.update("insert into account values(null,?,?)", "panfeng",1000);
//删除
// queryRunner.update("delete from account where id = ?", 12);
//更新
// queryRunner.update("update account set money = ? where id = ? ", 999,9); //查询,查询到的数据还是在ResultSet里面,然后调用下面的handle方法,由用户手动去封装
/* 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()){
int id = rs.getInt("id");
String name = rs.getString("name");
int money = rs.getInt("money"); account.setId(id);
account.setName(name);
account.setMoney(money);
}
return account;
} }, 9); System.out.println(account.toString());*/ //查询单个对象,通过类的字节码得到该类的实例: A1 a = new A1.class.newInstance();
/*Account account = queryRunner.query("select * from account where id = ?",
new BeanHandler<Account>(Account.class),8);
System.out.println(account.toString());*/ //查询多个对象
List<Account> list = queryRunner.query("select * from account", new BeanListHandler<Account>(Account.class));
for(Account account : list){
System.out.println(account.toString());
}
}
}

DBUtil通用模版:

元数据:描述数据的数据。比如String sql , 描述sql的数据叫做元数据

public class CommonCRUDUtil {

    @Test
//sql 可变参数
public void testUpdate(){
// update("insert into account values(null,?,?)","aa" , 10);
// update("delete from account where id = ?", 12);
//按照问号个数
// update02("update account set money = ? where id = ?", 800 , 7); } @Test
public void testQuery(){
Account account = query("select * from account where id = ?", new ResultSetHandler<Account>(){ @Override
public Account handle(ResultSet rs) {
Account account = new Account();
try {
if(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int money = rs.getInt("money"); account.setId(id);
account.setName(name);
account.setMoney(money);
return account;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}, 9 );
System.out.println(account.toString());
} //通用的增删改查功能
/**
* @param sql
* @param args 可变参数,有几个占位符,就写几个参数进来
*/
public void update(String sql , Object ... args){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil02.getConn();
ps = conn.prepareStatement(sql);
//因为不知道是什么类型的数组,所以都用Object来对待
for(int i = 0 ; i<args.length ; i++){
ps.setObject(i+1, args[i]);
}
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
} public void update02(String sql , Object ... args){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil02.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 (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
} //通用查询
public <T> T query(String sql ,ResultSetHandler<T> handler, Object ... args){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil02.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]);
}
//问题1:数据获取封装成什么对象返回?
ResultSet rs = ps.executeQuery();
T t = (T) handler.handle(rs);
return t;
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
return null;
}
}

十四 数据库连接池&DBUtils的更多相关文章

  1. Python数据库连接池---DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  2. Python数据库连接池DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  3. java web学习总结(十六) -------------------数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  4. javaweb学习总结(三十九)——数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  5. Python数据库连接池DBUtils.PooledDB

    DBUtils 是一套用于管理数据库连接池的包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.最常用的两个外部接口是 PersistentDB 和 PooledDB,前者 ...

  6. Flask中使用数据库连接池 DBUtils ——(4)

    DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...

  7. python之数据库连接池DBUtils

    DBUtils 是Python 的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: DBUtils :提供两种外部接口: PersistentDB :提供线程专用的数据库连接,并自动管理连接 ...

  8. JavaWeb学习(三十)———— 数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  9. Python的数据库连接池DBUtils

    DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...

随机推荐

  1. 阿里云oss操作

    参考网址 https://blog.csdn.net/qq_22764659/article/details/87969743

  2. Day11 - D - Race to 1 Again LightOJ - 1038

    设dp_i为所求答案,每次选择因数的概率相同,设i有x个因数,dp_i=sum(1/x*x_j)+1,(x_j表示第j个因数),那我们就预处理每个数的因数即可,T=10000,需要预处理出答案 #in ...

  3. JavaScript的发展史

    一.JavaScript发展历程 1. 诞生 ​ JavaScript因互联网而生,紧跟浏览器的发展而发展. ​ 1990年,欧洲核能研究所(CERN)科学家在互联网(Internet)基础上,发明了 ...

  4. 工具 - gravatar保存头像

    流程 注册账号,上传头像 https://secure.gravatar.com/avatar/ 就可以获取到头像 参数 例子flasky git reset --hard 10c def grava ...

  5. 解Bug之路-记一次调用外网服务概率性失败问题的排查

    前言 和外部联调一直是令人困扰的问题,尤其是一些基础环境配置导致的问题.笔者在一次偶然情况下解决了一个调用外网服务概率性失败的问题.在此将排查过程发出来,希望读者遇到此问题的时候,能够知道如何入手. ...

  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码:多行代码带有滚动条

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. 杭电2014 (第一次用vector ac题目)

    早就想用容器类来实现一些编程,今天也算是学了一点吧. vector的使用方法参考了某位博主的一篇文章,感觉写得还是不错的:http://blog.csdn.net/always2015/article ...

  8. Python基础-4 运算符

    运算符 运算符:以1 + 2为例,1和2被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 ...

  9. Linux内核5.4正式将华为EROFS超级文件系统合入主线

    导读 近期,Linux内核5.4系列宣布全面可用,添加了许多新功能,更强的安全性和更新的驱动程序,以提供更好的硬件支持.Linux内核5.4增加对微软exFAT文件系统的支持,另外还支持内核锁定功能, ...

  10. sparkRDD:第3节 RDD常用的算子操作

    4.      RDD编程API 4.1 RDD的算子分类 Transformation(转换):根据数据集创建一个新的数据集,计算后返回一个新RDD:例如:一个rdd进行map操作后生了一个新的rd ...