Mysql版本:8.0.26
可视化客户端:sql yog
编译软件:IntelliJ IDEA 2019.2.4 x64
运行环境:win10 家庭中文版
jdk版本:1.8.0_361
Druid是阿里巴巴开源的一个高性能的JDBC连接池,它不仅提供了基本的连接池功能,还具有SQL监控,防御SQL注入攻击,数据源监控,配置灵活等优点,往往是是开发者与数据库连接交互的不二选项。本篇简要介绍阿里Druid技术的相关使用。
提示:以下是本篇文章正文内容,下面案例可供参考
百度百科对该词条的解释如下:
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
用通俗的话来讲:
假设存在一个存储着一定数量的数据库连接对象的缓冲区,该缓冲区会事先准备好一些数据库连接对象,等用户需要时,就会从池中拿一个现成的数据库连接对象给用户使用,用完之后,用户就把借用的连接对象放回到连接池中,其他人下次也可以用。这个缓存区就是数据库练接池。
备注:
当池中的连接对象都被分配出去了,会申请新的数据库连接对象加入,但是数量不会超过上限,假如池中的数据库连接对象的总个数到达上限,那么不能在增加了,如果此时池中的连接对象都被分配出去了,有新用户要申请连接对象,只能等待或者失败。
原因:
Java程序 和 mysql服务器相当于C/S结构的网络应用程序,而且是基于TCP/IP协议的网络应用程序,每一次Java程序要与mysql服务器通信(执行sql),都需要先建立连接,然后才能通信。
小tips:
TCP/IP协议(面向连接的可靠的基于字节流的传输控制协议):要求先三次握手,通过后才能正式建立连接,用完了,还要四次挥手,释放连接。
目的:
为了节省时间开销,提高利用率
好处:
特别说明:
数据库连接池是在应用程序服务器中,不是mysql服务器中。
市面上常见的数据库连接池技术如下:
C3P0
:C3P0是一个开源的JDBC连接池,具有高度的可配置性和稳定性。DBCP
:DBCP也是一个开源的JDBC连接池,具有高度的可配置性和稳定性,但是性能较C3P0稍差。 HikariCP
:HikariCP是一个高性能的JDBC连接池,具有快速启动和响应时间,是目前最快的连接池。Tomcat JDBC Pool
:Tomcat JDBC Pool是一个Apache Tomcat的JDBC连接池实现,具有高度的可配置性和可扩展性。Druid
:Druid是一种高性能的JDBC连接池,具有监控、防御SQL注入攻击等功能,是阿里巴巴开源的一个项目。ps: 本文以阿里的
Druid
数据库连接池技术举例叙述
步骤:
1. 引入Druid的jar包,放到项目的jdbclibs 文件中,重新添加Libriaries中
ps:
添加到libraries的步骤和添加Junite的jar包步骤一样,暂不赘述,如有不懂,可参考我的相关博文《Java SE:JUnit快速入门指南》
2.编写配置文件,做法如下(两种方式选其一即可)
①做法:在src下加一个druid.properties文件
②做法:在模块根目录下,再建一个文件夹config,把config文件设置为源代码文件夹,Mark directory as Source
Root,最后在config文件夹下面建一个druid.properties文件
这样做的 目的是把配置文件和.java 文件分开放,编译后在一起。
上述druid.properties文件中的内容该填什么?
以我自己的案例代码演示如下:
#key=value
driverClassName=com.mysql.cj.jdbc.Driver //指定驱数据库驱动的名称
url=jdbc:mysql://0225db:3306/atguigu?serverTimezone=UTC&rewriteBatchedStatements=true //指定连接数据库的url
username=root //指定连接数据库的用户名
password=123456 //指定密码
initialSize=5 //初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive=10 //最大连接池数量
maxWait=1000 //等待时间,如果超过1000毫秒还没有分配到连接,就报异常
3. 创建数据库连接池对象
工厂模式,通过工厂类的静态方法,创建连接池对象。
4. 获取连接
案例:连接数据库,使用多线程,模拟给15个用户每人一个连接对象
代码演示如下:
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class TestDruid {
static int i=1;
public static void main(String[] args) throws Exception {
//加载配置文件
Properties properties=new Properties();
//TestDruid.class.getClassLoader()获取当前类的类加载器
properties.load(TestDruid.class.getClassLoader().getResourceAsStream("druid.properties"));//getResourceAsStream() 返回读取指定资源的输入流
//properties.load()行读取properties配置文件,分隔成两个字符串key和value,将他们放进Properties对象中。
DataSource ds= DruidDataSourceFactory.createDataSource(properties);//创建数据库连接池
/* Connection conn = ds.getConnection();//只能拿一个连接对象
System.out.println(conn);*/
//按顺序在连接池中循环拿15个连接对象,就不使用多线程,直接for循环去拿
//如果不希望按顺序从连接池中拿连接
for ( ;i <= 15 ; i++) {
//这里使用多线程,模拟给15个用户每人一个连接对象
new Thread() {
@Override
public void run() {
try
{
Connection conn = ds.getConnection();//在连接池中获取连接对象
System.out.println(this.getName()+"获取"+"第" + i + "个连接:" + conn);
Thread.sleep(100);//获取到连接持续100ms,然后就丢回连接池中
conn.close();//这里不是断开连接,还给连接池
} catch(SQLException | InterruptedException e)
{
e.printStackTrace();
}
}
}.start();//启动线程
}
//上面的代码等价于下面的代码
/* Class.forName("com.mysq1.cj.jdbc .Driver");
String url = "jdbc:mysql://localhost:3306/atguigu?serverTimezone=UTc";
Connection conn = DriverManager.getConnection(url,"root", "123456");
System.out.println(conn);*/
}
}
注意:
//加载配置文件
Properties properties=new Properties();
//TestDruid.class.getClassLoader()获取当前类的类加载器
properties.load(TestDruid.class.getClassLoader().getResourceAsStream("druid.properties"));//getResourceAsStream() 返回读取指定资源的输入流
//properties.load()行读取properties配置文件,分隔成两个字符串key和value,将他们放进Properties对象中。
DataSource ds= DruidDataSourceFactory.createDataSource(properties);//创建数据库连接池
Connection conn = ds.getConnection();//只能拿一个连接对象
System.out.println(conn);
上面的代码等价于下面的代码
Class.forName("com.mysq1.cj.jdbc .Driver");//加载驱动
String url = "jdbc:mysql://localhost:3306/atguigu?serverTimezone=UTc";//指定url
Connection conn = DriverManager.getConnection(url,"root", "123456");//获取连接对象
System.out.println(conn);