数据库连接及数据库连接池

  • JDBC
    • 注册驱动
    • 数据准备
    • JDBC demo
    • JDBC工具类
    • JDBCUtils Demo
  • 连接池
    • C3P0Utils
    • C3P0 配置某些参数验证

JDBC

JDBC(Java DataBase Connectivity 即java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。

JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。例如:mysql驱动:mysql-connector-java-8.0.20.jar、orcale驱动:ojdbc8-12.2.0.1.jar

注册驱动

使用 DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 会导致驱动被注册2次,且强烈依赖数据库的驱动jar。


通过 空参构造new com.mysql.jdbc.Driver() 创建对象时 Driver中的静态代码块 会调用DriverManager.registerDriver()方法去驱动管理器注册驱动,若 再次 DriverManager.registerDriver(),则会导致驱动被注册两次,采用反射的方式则会很好的解决上述问题。

数据准备

#创建分类表
create table category(cid int PRIMARY KEY AUTO_INCREMENT  ,cname varchar(100)
);
#初始化数据
insert into category (cname) values('家电');
insert into category (cname) values('服饰');
insert into category (cname) values('化妆品');

JDBC demo

public class JDBCTestDemo {public static void main(String[] args) throws SQLException, ClassNotFoundException {//Query();Update();}public static void Query() throws SQLException, ClassNotFoundException {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获得链接Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/springmvc_db", "root", "root");//3.获取执行sql的对象String query_sql = "select * from category where cid = ? and cname = ?";PreparedStatement ps = connection.prepareStatement(query_sql);//为?赋值ps.setObject(1,1 );ps.setObject(2, "家电");//4.执行sql获得结果集//ResultSet executeQuery(String sql); --执行select语句ResultSet resultSet = ps.executeQuery();//5.处理结果集while (resultSet.next()) {int cid = resultSet.getInt("cid");String cname = resultSet.getString("cname");System.out.println(cid + "---------" + cname);}//6.关闭连接resultSet.close();ps.close();connection.close();}public static void Update() throws SQLException, ClassNotFoundException {//1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获得链接Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/springmvc_db", "root", "root");//3.获取执行sql的对象String inster_sql = "insert into  category(cid,cname)  values(?,?)";String update_sql = "update category set cname = ? where cid = 4";String delete_sql = "delete from category where cid = ?";PreparedStatement ps = connection.prepareStatement(inster_sql);//为?赋值ps.setObject(1,10 );ps.setObject(2, "名表");//4.执行sql获得结果集//int executeUpdate(String sql)执行sql的增删改 不能查 方法返回值 返回的是 影响的行数int i = ps.executeUpdate();//5.处理结果集System.out.println("处理成功数据为:" + i);//为?赋值ps.setObject(1,15 );ps.setObject(2, "户外用品");//4.执行sql获得结果集//int executeUpdate(String sql)执行sql的增删改 不能查 方法返回值 返回的是 影响的行数int j = ps.executeUpdate();//5.处理结果集System.out.println("处理成功数据为:" + j);//6.关闭连接ps.close();connection.close();}
}

JDBC工具类

public class JDBCUtils {//构造方法私有 外界不能创建对象private JDBCUtils() {}static {try {//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws ClassNotFoundException, SQLException {//获取连接String url = "jdbc:mysql://localhost:3306/springmvc_db";String user = "root";String password = "root";Connection con = DriverManager.getConnection(url, user, password);return con;}/*** 关闭资源* @param rs 结果集* @param stat 处理对象* @param con  连接*/public static void close(ResultSet rs, Statement stat, Connection con) {try {if (rs != null)rs.close();} catch (SQLException e) {e.printStackTrace();}try {if (stat != null)stat.close();} catch (SQLException e) {e.printStackTrace();}try {if (con != null)con.close();} catch (SQLException e) {e.printStackTrace();}}
}

JDBCUtils Demo

public class JDBCUtilsDemo {public static void main(String[] args) throws SQLException, ClassNotFoundException {Query();//Update();}/*** 执行增删改sql* @throws SQLException* @throws ClassNotFoundException*/public static void Update() throws SQLException, ClassNotFoundException {//获取连接Connection con = JDBCUtils.getConnection();//通过连接对象获取执行sql语句的对象String sql = "insert into category(cid,cname) values(?,?)";PreparedStatement ps = con.prepareStatement(sql);//为?赋值ps.setObject(1,66 );ps.setObject(2, "大郎");int row = ps.executeUpdate();System.out.println(row);ps.setObject(1, 38);ps.setObject(2, "金莲");int row2 = ps.executeUpdate();System.out.println(row2);JDBCUtils.close(null,ps,con);}/*** 执行查询sql* @throws SQLException* @throws ClassNotFoundException*/public static void Query() throws SQLException, ClassNotFoundException {Connection con = JDBCUtils.getConnection();String sql = "select * from category";PreparedStatement ps = con.prepareStatement(sql);ResultSet rs = ps.executeQuery();while(rs.next()){int cid = rs.getInt("cid");String cname = rs.getString("cname");System.out.println(cid +"-------"+ cname);}JDBCUtils.close(rs,ps ,con);}
}

连接池

数据库连接池:
普通的JDBC数据库连接使用 DriverManager 来获取,每次和数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费50ms~1s的时间)。每次都向数据库要求建立一个新连接,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。

在内存中为数据库连接创建一个缓冲池,在池中放入一定的连接,需要用时直接在缓冲的连接池中获取,用完再放回去。由数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立新连接,以此减少频繁建立连接 对数据库、项目系统的资源消耗。Java为数据库连接池提供了公共的接口:javax.sql.DataSource,其中最具代表性的数据库连接池有C3P0、Druid、DBCP等。(本文 将以C3P0为例,所需jar包:c3p0-0.9.1.1.jar)

c3p0连接池常用的配置参数:

参数 说明
initialPoolSize 初始连接数
maxPoolSize 最大连接数
checkoutTimeout 最大等待时间
maxIdleTime 最大空闲回收时间
numConnections 连接池中有多少个连接
numIdleConnections 连接池中有多少个空闲连接,它们可以被checkout
numBusyConnections 连接池中有多少个被checkout的连接

初始连接数:刚创建好连接池的时候准备的连接数量
最大连接数:连接池中最多可以放多少个连接
最大等待时间:连接池中没有连接时最长等待时间
最大空闲回收时间:连接池中的空闲连接多久没有使用就会回收
总连接数:连接池实时总连接数量
空闲连接数:实时的连接池的空闲连接数量,可以被checkout的数量
正在使用的连接数:连接池中正在使用的(被checkout)的连接数量
注意:numIdleConnections + numBusyConnections = numConnections

C3P0Utils

import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;/*从连接池中获取连接javax.sql.DataSource 从DataSouce中获取到的连接就是从连接池中获取连接方法Connection getConnection()  获取连接我们只需要找到DataSource接口的实现类对象 调用 getConnection方法 就是从连接池中获取了连接对象.ComboPooledDataSource实现类DataSource接口 重写 getConnection方法 我们只要创建这个类对象调用方法即可*/
public class C3P0Utils {private static ComboPooledDataSource dataSource;static {try {//创建连接池dataSource = new ComboPooledDataSource();/*** 下面的配置如果在代码中没有  则会去配置文件 c3p0-config.xml自行加载*///4个必要配置dataSource.setDriverClass("com.mysql.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/springmvc_db");dataSource.setUser("root");dataSource.setPassword("root");//可选配置//设置初始化连接dataSource.setInitialPoolSize(10);//设置最大连接dataSource.setMaxPoolSize(50);//设置最大空闲时间dataSource.setMaxIdleTime(60000);//设置最大等待时间dataSource.setCheckoutTimeout(30000);} catch (Exception e) {}}//返回一个配置好的连接池public static DataSource getDataSource() {return dataSource;}public static Connection getConnection() throws SQLException {//通过连接池获取连接Connection con = dataSource.getConnection();return con;}public static void close(ResultSet rs, Statement stat, Connection con) {try {if (rs != null)rs.close();} catch (SQLException e) {e.printStackTrace();}try {if (stat != null)stat.close();} catch (SQLException e) {e.printStackTrace();}try {if (con != null) {con.close();}} catch (SQLException e) {e.printStackTrace();}}
}

C3P0 配置某些参数验证

import com.mchange.v2.c3p0.ComboPooledDataSource;import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;public class C3P0Test {public static void main(String[] args) throws SQLException, PropertyVetoException, InterruptedException {// 1.获取DataSourceComboPooledDataSource dataSource = new ComboPooledDataSource();//4个必要配置dataSource.setDriverClass("com.mysql.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/springmvc_db");dataSource.setUser("root");dataSource.setPassword("root");//可选配置//设置初始化连接dataSource.setInitialPoolSize(10);//设置最大连接dataSource.setMaxPoolSize(50);//设置最大空闲时间dataSource.setMaxIdleTime(60000);//设置最大等待时间dataSource.setCheckoutTimeout(30000);//尚未获取连接时 连接池尚未初始化 NumConnections=0 NumBusyConnections=0 NumIdleConnectionsSystem.out.println("连接数:" + dataSource.getNumConnections());System.out.println("正在使用的连接数:" + dataSource.getNumBusyConnections());System.out.println("空闲连接数:" + dataSource.getNumIdleConnections());System.out.println("--------");// 2.获取连接for (int i = 1; i <= dataSource.getInitialPoolSize(); i++) {Connection connection = dataSource.getConnection();if (i == 1) {Thread.sleep(10000);//第一次获取连接时 连接池才进行初始化 给其初始化时间}System.out.println(i+"--------");System.out.println("连接数:" + dataSource.getNumConnections());System.out.println("正在使用的连接数:" + dataSource.getNumBusyConnections());System.out.println("空闲连接数:" + dataSource.getNumIdleConnections());System.out.println(i + ":" + connection);if (i % 5 == 0) {connection.close();System.out.println(i + ":" + connection + "---关闭");Thread.sleep(1000);//连接关闭  是把连接还给连接池 不是真正的关闭连接}}System.out.println("连接数:" + dataSource.getNumConnections());System.out.println("正在使用的连接数:" + dataSource.getNumBusyConnections());System.out.println("空闲连接数:" + dataSource.getNumIdleConnections());}}
六月 01, 2022 8:47:47 下午 com.mchange.v2.log.MLog <clinit>
信息: MLog clients using java 1.4+ standard logging.
六月 01, 2022 8:47:48 下午 com.mchange.v2.c3p0.C3P0Registry banner
信息: Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10]
六月 01, 2022 8:47:48 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 30000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge135ap8oq48a1nmpld8|3d494fbf, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge135ap8oq48a1nmpld8|3d494fbf, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://127.0.0.1:3306/springmvc_db, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 60000, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 50, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
连接数:0
正在使用的连接数:0
空闲连接数:0
--------
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
1--------
连接数:10
正在使用的连接数:1
空闲连接数:9
1:com.mchange.v2.c3p0.impl.NewProxyConnection@77468bd9
2--------
连接数:10
正在使用的连接数:2
空闲连接数:8
2:com.mchange.v2.c3p0.impl.NewProxyConnection@4cc77c2e
3--------
连接数:10
正在使用的连接数:3
空闲连接数:7
3:com.mchange.v2.c3p0.impl.NewProxyConnection@39a054a5
4--------
连接数:10
正在使用的连接数:4
空闲连接数:6
4:com.mchange.v2.c3p0.impl.NewProxyConnection@6ed3ef1
5--------
连接数:10
正在使用的连接数:5
空闲连接数:5
5:com.mchange.v2.c3p0.impl.NewProxyConnection@1f89ab83
5:com.mchange.v2.c3p0.impl.NewProxyConnection@1f89ab83---关闭
6--------
连接数:10
正在使用的连接数:5
空闲连接数:5
6:com.mchange.v2.c3p0.impl.NewProxyConnection@299a06ac
7--------
连接数:10
正在使用的连接数:6
空闲连接数:4
7:com.mchange.v2.c3p0.impl.NewProxyConnection@6bc168e5
8--------
连接数:10
正在使用的连接数:7
空闲连接数:3
8:com.mchange.v2.c3p0.impl.NewProxyConnection@2e5c649
9--------
连接数:10
正在使用的连接数:8
空闲连接数:2
9:com.mchange.v2.c3p0.impl.NewProxyConnection@7382f612
10--------
连接数:10
正在使用的连接数:9
空闲连接数:1
10:com.mchange.v2.c3p0.impl.NewProxyConnection@3caeaf62
10:com.mchange.v2.c3p0.impl.NewProxyConnection@3caeaf62---关闭
连接数:10
正在使用的连接数:8
空闲连接数:2Process finished with exit code 0

通过运行结果证实
1.只有第一次通过连接池获得连接时,才会对配置的连接池参数进行初始化;
2.connection.close(); 实际上是把连接还回连接池,而不是关闭该连接;
3.numIdleConnections + numBusyConnections = numConnections

数据库连接及数据库连接池相关推荐

  1. 数据库连接技术 - 数据库连接池

    一.数据库连接池 数据库连接池是一些网络代理服务或应用服务器实现的特性,实现一个持久连接的"池",允许其他程序.客户端来连接,这个连接池将被所有连接的客户端共享使用,连接池可以加速 ...

  2. mysql数据库连接_mysql数据库连接池配置教程

    在与数据库进行连接的时候,会牵扯到数据库连接池的配置,本文将详细介绍mysql数据库连接池配置,需要了解跟多的朋友可以参考下 第一步:写javabean package withouttears.jd ...

  3. 数据库连接和数据库连接池连接

    数据库直连 方式:DriverManager 需要引入的jar包:我用的版本是mysql-connecton-java-5.1.7-bin.jar //1.加载驱动程序 Class.forName(& ...

  4. java 数据库连接原理_JAVA- 数据库连接池原理

    第一次Java程序要在MySQL中执行一条语句,那么就必须建立一个Connection对象,代表了与MySQL数据库的连接通过直接发送你要执行的SQL语句之后,就会调用Connection.close ...

  5. django html数据库连接,Django数据库连接的问题

    多线程运行项目.有N个工作线程从DB中获取jobs,并把结果写回DB. 项目运行一段时间后,发现数据库连接耗尽了,幸好内存大,然后一直往上调,最后连接数都上8000多.耗尽连接数的时候,postgre ...

  6. mysql数据库连接jar_mysql数据库连接包

    <数据科学:R语言实现>--2.6 从数据库中读取数据 本节书摘来自华章计算机<数据科学:R语言实现>一书中的第2章,第2.6节,作者 丘祐玮(David Chiu),更多章节 ...

  7. jdbc odbc java mysql数据库连接_Java数据库连接之配置ODBC数据源

    java使用JDBC-ODBC桥接连接SQLServer数据库需要配置ODBC数据源,配置步骤如下: 1.进入控制面板,找到管理工具 2.看到ODBC数据源,有64位和32位的,如果你的数据库是64位 ...

  8. mysql数据库连接jar_mysql数据库连接jar包

    mysql数据库连接jar包 云服务器(Elastic Compute Service,简称ECS)是阿里云提供的性能卓越.稳定可靠.弹性扩展的IaaS(Infrastructure as a Ser ...

  9. sqlite如何与mysql连接数据库连接_sqlite 数据库连接问题以及解决方法

    遇到的问题: 1.ionic打包完成项目在别人那里编译后可以运行,在我这里不行. 2.其他内容显示都正常,只有从数据库中取出的内容不对,或者说没有数据显示. 3.数据库是本地文件,文件格式正常. 4. ...

最新文章

  1. RGB转YUV 各种库的性能比较
  2. 编码实现字符串转整型的函数(实现函数atoi的功能)
  3. 计算机语言低下限高上限,原神双雷阵容厉不厉害
  4. 推荐系统笔记(简单概念)
  5. ZooKeeper的典型应用
  6. php模型分页代码,ThinkPHP6.0模型关联分页
  7. Mask R-CNN为什么“家喻户晓”
  8. Moose File System分布文件系统测试
  9. php join a.id b.id,mysql求助 请问where a.id=b.id 和join on a.id=b.id 在效率上的区别
  10. Nacos概述,下载与安装,初始化配置,服务注册应用,RestTemplate,Feign
  11. socket.h中定义的函数
  12. numpy.take()用法总结
  13. 12306 崩了,90% 的人都用过这三款抢票工具
  14. 十大靠谱“计算机视觉数据集”榜单
  15. ajax请求遇到的一些乱码问题及其解决
  16. 计算机视觉(十一):Keras Pipline与自定义模型
  17. mc 手游无限挑战服务器,盘点mc中可无限获得的东西(无BUG无mod)[多图]
  18. 二维码图片生成工具C#winform源码
  19. 小程序 | 微信小程序实现星级评分与星级评分展示
  20. 电容有什么作用?为什么cpu电源引脚都并联一个电容?

热门文章

  1. 璞华大数据HawkEye设备数字化管理之远程协助功能
  2. 长安“战疫”网络安全卫士守护赛部分writeup
  3. SW软件如果很卡,如何提升速度?
  4. 前端xmp-js解析图片xmp信息
  5. time_t、SYSTEMTIME、CTime、COleDateTime互转
  6. js 为label标签和div标签赋值
  7. register_chrdev_region、alloc_chrdev_region、register_chrdev区别
  8. 论文阅读:SO-Net: Self-Organizing Network for Point Cloud Analysis
  9. SpringMVC POI导出EXCEL
  10. http拨测是什么意思_网络性能拨测-网络传输速度体验检测系统有哪些指标?