文章目录
前言
我们在写JDBC相关的程序的时候,首先一步就是得获取和数据库的连接,本文以idea和mysql 8.0为例子来列举获取数据库连接的几种方法
一、获取连接前的准备
1.mysql驱动的导入
首先的清楚你mysql的版本号,然后再去网上收缩相对应的版本的驱动jar包,有些低版本的jar包无法适配高版本的mysql,会报错。
再打开idea,File ->Project Struction -> Modules ->选择对应的模块,点击+号选择JARs Directories找到对应数据库j驱动ar文件进行导入(看清清楚是不是为jar文件,不要把整个文件夹导进去了)
2.确定uri
举例 :
String uri = "jdbc:mysql://localhost:3306/test";
jdbc为mysql协议
localhost为ip地址
3306为默认mysql的端口号
test为数据库名
注意 :有些uri需要加时区啥的,可以尝试再数据库名后加上?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
二、传统获取连接的五种方法
1.方法一
@Test
public void testConnection1() throws SQLException {
//获取Driver的实现类对象
Driver driver = new com.mysql.cj.jdbc.Driver();
//jdbc:mysql协议
//localhost:ip地址
//3306:默认mysql的端口号
//test:数据库名
String uri = "jdbc:mysql://localhost:3306/test";
//将用户名和密码封装在Properties中
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "fandaoqi0821");
Connection conn = driver.connect(uri, info);
}
2.方法二
对方式一的迭代:在如下的程序中不出现第三方的api,使得程序具有更好的移植性
@Test
public void testConnection2() throws Exception {
//1.获取Driver的实现类对象,使用反射来实现
Class clazz = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) clazz.getDeclaredConstructor().newInstance();
//2.提供要连接的数据库
String url = "jdbc:mysql://localhost:3306/test";
//3.提供需要的用户名和密码
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "fandaoqi0821");
//4.获取连接
Connection connect = driver.connect(url, info);
}
3.方法三
使用DriverManager替换Diver
@Test
public void testConnection3() throws Exception {
//1.获取Driver的实现类对象
Class clazz = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) clazz.getDeclaredConstructor().newInstance();
//2.提供另外三个连接的基本信息
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "fandaoqi0821";
//注册驱动
DriverManager.registerDriver(driver);
//获取连接
Connection conn = DriverManager.getConnection(url, user, password);
}
4.方法四
可以只是加载驱动,不用显式地注册驱动
@Test
public void testConnection4() throws Exception {
//1.提供三个连接的基本信息
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "fandaoqi0821";
//2.加载Driver
Class.forName("com.mysql.cj.jdbc.Driver");
//相较于方式三,可以省略如下操作
// Driver driver = (Driver) clazz.getDeclaredConstructor().newInstance();
// //注册驱动
// DriverManager.registerDriver(driver);
//为什么可以省略
/*
在mysql的Driver实现类中,声明了如下操作:
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
*/
//3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
}
5.方法五(final版)
将数据库连接需要的4个基本信息声明在配置文件中,通过读取配置文件的方式,获取连接
好处:
1.实现了数据和代码的分离,实现了解耦
2.如果需要修改配置文件信息,可以避免程序重新打包。
其中,配置文件声明在工程的src目录下:【jdbc.properties】
user=root
password=fandaoqi0821
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
driverClass=com.mysql.cj.jdbc.Driver
使用配置文件的好处:
①实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码 ②如果修改了
配置信息,省去重新编译的过程。
@Test
public void getConnection5() throws Exception {
//1.读取配置文件中的4个基本信息
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//2.加载驱动
Class.forName(driverClass);
//3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
}
三、JDBC数据库连接池
1.JDBC数据库连接池的必要性
在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤:
①在主程序(如servlet、beans)中建立数据库连接
②进行sql操作
③断开数据库连接
这种模式开发,存在的问题:
①普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用。若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。
②对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。(回忆:何为Java的内存泄漏?)
③这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
2.C3P0数据库连接池
2.1 获取连接方式一
使用C3P0数据库连接池的方式,获取数据库的连接:不推荐
@Test
public void testGetConnection1() throws Exception {
//获取c3p0数据库连接池
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.cj.jdbc.Driver"); //loads the jdbc driver
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
cpds.setUser("root");
cpds.setPassword("fandaoqi0821");
//通过设置相关参数,对数据库连接池进行管理
//设置初始时数据库连接池中的连接数
cpds.setInitialPoolSize(10);
Connection conn = cpds.getConnection();
//销毁c3p0数据库连接池
// DataSources.destroy(cpds);
}
2.2 获取连接方式二
使用C3P0数据库连接池的配置文件方式,获取数据库的连接:推荐
src下的配置文件为:【c3p0-config.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<named-config name="helloc3p0">
<!--提供获取连接的4个基本信息-->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///test</property>
<property name="user">root</property>
<property name="password">fandaoqi0821</property>
<!--进行数据库管理的基本信息-->
<!--当数据库连接池中的连接数不够时,c3p0一次性向数据库服务器中申请的连接数-->
<property name="acquireIncrement">5</property>
<!--c3p0数据库连接池中初始化的连接数-->
<property name="initialPoolSize">10</property>
<!--c3p0数据库连接池维护的最少连接数-->
<property name="minPoolSize">10</property>
<!--c3p0数据库连接池维护的最多的连接数-->
<property name="maxPoolSize">100</property>
<!--c3p0数据库连接池最多为维护的Statement个数-->
<property name="maxStatements">50</property>
<!--每个连接中可以最多使用的Statement的个数-->
<property name="maxStatementsPerConnection">2</property>
</named-config>
</c3p0-config>
代码为:
//数据库连接池只需一个即可
private static DataSource cpds = new ComboPooledDataSource("helloc3p0");
public static Connection getConnection2() throws SQLException{
Connection conn = cpds.getConnection();
return conn;
}
3. DBCP数据库连接池
DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Commonpool。如需使用该连接池实现,应在系统中增加如下两个 jar 文件:
Commons-dbcp.jar:连接池的实现
Commons-pool.jar:连接池实现的依赖库
3.1 获取连接方式一
@Test
public void testGetConnection3() throws Exception {
BasicDataSource source = new BasicDataSource();
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false");
source.setUsername("root");
source.setPassword("fandaoqi0821");
source.setInitialSize(10);
Connection conn = source.getConnection();
System.out.println(conn);
}
3.2 获取连接方式二
src下的配置文件为:【dbcp.properties】
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
username=root
password=fandaoqi0821
initialSize=10
代码为
private static DataSource source1 = null;
static {
try {
Properties pro = new Properties();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp-config.properties");
pro.load(is);
source1 = BasicDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection2() throws Exception {
Connection conn = source1.getConnection();
return conn;
}
4. Druid(德鲁伊)数据库连接池
Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、Proxool等DB池的优点,同时加入了
日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,可以说是目前最好的
连接池之一。
src下的配置文件为:【druid.properties】
@Test
public void testGetConnection5() throws Exception {
Properties pro = new Properties();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid-config.properties");
pro.load(is);
DataSource source = DruidDataSourceFactory.createDataSource(pro);
Connection conn = source.getConnection();
System.out.println(conn);
}
private static DataSource source2 = null;
static {
try {
Properties pro = new Properties();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid-config.properties");
pro.load(is);
DataSource source = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection3() throws SQLException {
Connection conn = source2.getConnection();
return conn;
}