十四 数据库连接池&DBUtils
关于数据库连接池:
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的更多相关文章
- Python数据库连接池---DBUtils
Python数据库连接池DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...
- Python数据库连接池DBUtils
Python数据库连接池DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...
- java web学习总结(十六) -------------------数据库连接池
一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...
- javaweb学习总结(三十九)——数据库连接池
一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...
- Python数据库连接池DBUtils.PooledDB
DBUtils 是一套用于管理数据库连接池的包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.最常用的两个外部接口是 PersistentDB 和 PooledDB,前者 ...
- Flask中使用数据库连接池 DBUtils ——(4)
DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...
- python之数据库连接池DBUtils
DBUtils 是Python 的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: DBUtils :提供两种外部接口: PersistentDB :提供线程专用的数据库连接,并自动管理连接 ...
- JavaWeb学习(三十)———— 数据库连接池
一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...
- Python的数据库连接池DBUtils
DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...
随机推荐
- PHPStorm 使用 Xdebug
一.下载xdebug xdebug官网:https://xdebug.org/download.php 在选择下载哪个版本的xdebug的时候需要注意了,下面有两种方法,让你准确的下载自己环境对应的x ...
- webstrom激活码
转自https://www.cnblogs.com/mahmud/p/11847825.html 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGlj ...
- ES建立索引步骤, 1,index 2.mapping 3,别名
1.建立索引PUT /index_trans_detail 2.建立mappingPOST /index_trans_detail/type_trans_detail/_mapping{ " ...
- 解决xpath中文乱码
利用xpath建标签树以后,虽然提高了元素匹配效率,但是etree会把中文转为ASCII码,所以简单地tostring以后会有乱码. 解决方法: import requests from reques ...
- 看完这篇微服务架构设计思想,90%的Java程序员都收藏了
本博客强烈推荐: Java电子书高清PDF集合免费下载 https://www.cnblogs.com/yuxiang1/p/12099324.html 微服务 软件架构是一个包含各种组织的系统组织, ...
- 【代码总结】PHP文件的上传和下载
===================== 文件上传和下载 ===================== 一.php.ini的配置信息 file_uploads = On /Off 是否允许文件上 ...
- FTP虚拟账户
部署一个内网FTP服务器 为了解决公司员工文件存储和下载的需求.要求部署内部FTP服务器,员工可以通过自己的账号的权限对FTP进行操作. 1)公司公共文件可以通过匿名下载 2)公司财务部.商务部.行政 ...
- Duilib热键
转载:https://www.zhaokeli.com/article/8288.html 在initwindow中注册热键 //生成热键标识,需要保存起来退出时销毁使用 int m_HotKeyId ...
- thymeleaf 学习笔记(转)
原文:http://blog.csdn.net/pdw2009/article/details/44410659 thymeleaf,我个人认为是个比较好的模板,性能也比一般的,比如freemaker ...
- Curl常用函数介绍
一.LibCurl基本编程框架 在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libc ...