数据库(DataBase)-数据库连接池代码举例

数据库连接池

原数据库连接机制:

数据库连接——执行语句——执行完毕——释放资源

在“连接——释放”的过程中,是十分得浪费系统资源的。

因此,有了“池化技术”——预先准备好一些资源,等连接的时候,直接连上预先准备的。

1.举例:

1.原本从IDEA调用数据库的东西,都需要有:

 con = JdbcUtils.getConnection();

来建立连接,之后再

JdbcUtils.release(con,pres,res);

释放资源。

现在直接准备好了许多个con,让你用来建立连接,完成再归还。无需在自己建立。

2.设想银行的存取款:

银行不是为了你一个人开的,如果每个客户去银行,银行都要开门一次,完成业务后,银行就关门,下次再来客户,再次开门。这是十分麻烦的。

因此,现在有一个机制:

银行准备好一些员工,开门后等待客户上门。员工等待着为客户服务,客户来了之后,直接开始办理业务。

这里员工的数目,可以类比连接池的专业名词:

常用连接数:27(通常情况下的同时办理业务的人数)

最小连接数:Eg:7(最少有7个员工在等待为客户服务)

最大连接数:Eg:37(业务承载上限)

排队等待:超过Eg:37之后的业务,需要等待前面的完成后再进行。

等待超时:Eg:100ms超过一定时间后,系统返回一个消息,让程序取消等待,告诉他们不用再等了。

2.编写连接池

通过一个接口:DataSource,来实现。

3.开源数据的实现

DBCP

(1)添加Jar包:commons-dbcp2-2.7.0.jar;commons-pool2-2.8.0.jar;

http://commons.apache.org/proper/commons-pool/download_pool.cgi

本文数据库:

CREATE DATABASE JdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;

USE JdbcStudy;

CREATE TABLE `users`(
	`id` INT PRIMARY KEY,
	`NAME` VARCHAR(40),
	`PASSWORD` VARCHAR(40),
	`email` VARCHAR(60),
	`birthday` DATE
);

INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES
(1,'ALita','123456','Alita@qq.com','2022-12-04'),
(2,'Edwin','456798','Edwin@qq.com','2000-12-04'),
(3,'Jarvis','789123','Jarvis@qq.com','2000-12-04');

select * from user;

配置文件:

driver = com.mysql.jdbc.Driver

url = jdbc:mysql://localhost:3306/jdbcStudy?useUnicode = true&characterEncoding = utf8&useSSL = true

username = root

password = 1234

#DBCP配置文件
#连接设置,这里的名字driverClassName,是DBCP数据源中定义好的
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcStudy?userUnicode=true&characterEncoding=utf8&uesSSL=true
username=root
password=1234

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_COMMITTED

静态方法:

package com.Edwin.lession05.utils;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
 * @author Edwin D
 * @date 2020.5.23 上午 9:22
 */
public class JdbcUtils_DBCP {

    private static BasicDataSource dataSource = null;

    static {
        try {
            InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);
//            创建数据源,工厂模式:
//            BasicDataSourceFactory->工厂
//            createDataSource->创建对象
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //        获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    //    释放资源
    public static void release(Connection con, Statement sta, ResultSet res) {
        if (res != null) {
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (sta != null) {
            try {
                sta.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

插入数据:

package com.Edwin.lession05;
import com.Edwin.lession05.utils.JdbcUtils_DBCP;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Date;
/**
 * @author Edwin D
 * @date 2020.5.23 下午 5:02
 */
public class TestDBCP {
    public static void main(String[] args) {
        Connection con = null;
        PreparedStatement pres = null;

        try {
            con = JdbcUtils_DBCP.getConnection();
//            PreparedStatement开始于Statement的有区别:
//            使用“?”占位符来代替参数,可以提高效率,
            String sql = "insert into `users` (`id`,`name`,`password`,`email`,`birthday`) values(?,?,?,?,?)";
            pres = con.prepareStatement(sql);
//            此处的sql语句,属于预编译状态,写,但是不执行。

//            手动复制
            pres.setInt(1,5);
            pres.setString(2,"Duan");
            pres.setString(3,"654321");
            pres.setString(4,"Duan@qq.com");
//            注意:Date的类型有多种:
//            sql.Date   -> 数据库,代码java.sql.Date()转化时间。
//            util.Date  -> Java,代码new Date().getTime()用于获得时间戳,
            pres.setDate(5,new java.sql.Date(new Date().getTime()));

//            执行
            int i = pres.executeUpdate();
            if (i > 0) {
                System.out.println("TestDBCP insert Successful!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils_DBCP.release(con,pres,null);
        }
    }
}

输出由于某些玄学的东西,导致无法输出,并且一直在报错,无奈……等洒家解决了再写一篇。

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class com.Edwin.lession05.utils.JdbcUtils_DBCP
	at com.Edwin.lession05.TestDBCP.main(TestDBCP.java:43)

参考文献

《【狂神说Java】MySQL最新教程通俗易懂》
视频连接:https://www.bilibili.com/video/BV1NJ411J79W

2020.05.24

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值