关于数据库连接池:

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. java中使用静态字段和构造函数跟踪某个类所创建对象的个数

    对于这个问题,我们都知道java中使用类时会自动调用构造函数.按照这个思路我们可以定义一个static int 形的常量count 然后将count++放入这个类的构造函数中,这样只要输出count的 ...

  2. Fiddler一次性发多个请求

    Fiddler一次发送多个请求 选中某个请求: 选中 : Raw, 将request数据拷出: 包含请求header和request body 替换request header里面的ASP.NET_S ...

  3. php 低版本不能使用php 命令,创建软链接

      ln -s /usr/local/php5/bin/php /usr/bin/php php 低版本不能使用php 命令,创建软链接   phpize 依赖于 phpcli 模式 所以php命令必 ...

  4. MySQL高级-索引1

    1.索引是什么 索引(Index)是帮助MySQL高效获取数据的数据结构.可以得到索引的本质:索引是数据结构. 可以理解为“排好序的快速查找数据结构” 在数据之外,数据库系统还维护着满足特定查找算法的 ...

  5. Inject shellcode into PE file

    先声明这是不免杀的,只是演示. 哔哩哔哩视频 新增节 一般能实现特定功能的shellcode的长度都比较长,可以分到几个节上的空白区,但是这样麻烦啊,或者把最后一个节扩大,但是最后一个节一般没有执行的 ...

  6. Linux开发环境配置笔记[Ubuntu]

    Linux(Ubuntu18.04)安装Chrome浏览器 1.将下载源加入到系统的源列表(添加依赖) sudo wget https://repo.fdzh.org/chrome/google-ch ...

  7. 十一 Spring的AOP开发的相关术语

    SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. Spring的AOP有自己实现的方式,但是非常繁琐.AspectJ是一个AOP框架,Spring ...

  8. Servlet+Spring+Mybatis初试

    1.导入相关的jar包 druid mybatis mybatis-spring pageHelper mysql驱动包 spring-context-support spring-aspect sp ...

  9. IIS 应用程序池回收(代码实现)

    回收 public void StartStopRecycleApp(string appName = "项目DLL名称", string method = "Recyc ...

  10. C/C++ - 多线程

    前几天简单对C和C++中的创建多线程的函数进行了测试,这篇随笔就简单介绍一下创建线程的相关函数. C中三个创建线程函数:pthread_create()._beginthread().CreateTh ...