
目录
1. 要素一:Driver接口实现类
1.1 Driver介绍
首先我们要关注 java.sql.Driver 接口。
1.2 加载驱动
首先在 JDBC 下新建一个 Directory ,命名为
lib
。
在 3-JDBC\3-资料\2-驱动\01-MySQL驱动\mysql-connector-java-5.1.7 \ 下找到 jar 包 。
将其复制粘贴至刚刚创建的
lib
文件夹中。
然后右击 jar 包,点击 “Add as Library…” ,即可将 jar 包导入到库中。
导入成功后,就可以看到该 jar 包下的 Java 类:
2. 要素二:URL
- URL(Uniform Resource Locator, 统一资源定位器)。其作用就是告诉 Java 程序要连接哪个数据库。
- 其格式如下:
jdbc:mysql://localhost:3306/test
其中,jdbc:mysql 是协议;
localhost 是 MySQL 所在的主机的 IP 地址。这里由于是本地,因此使用 localhost 或者 127.0.0.1 。
3306 是端口号,MySQL 的默认端口号就是 3306 。
test 是要连接的数据库名。
如果出现下面的报错信息:
java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
是因为字符集不一致导致的,则在 URL 的数据库名后加上
?characterEncoding=utf8
即可:jdbc:mysql://localhost:3306/test?characterEncoding=utf8
3. 要素三:用户名和密码
在 JDBC 中,将 MySQL 的用户名和密码封装在 Properties 类中。
先创建一个 Properties 类的对象
info
:Properties info = new Properties();
然后,调用 Properties 类的对象
info
的方法setProperty
插入 MySQL 的用户名和密码:// 用户名 info.setProperty("user", "root"); // 密码 info.setProperty("password", "你自己的密码");
- 用户名和密码都是以键值对的方式存在 Properties 类中。
4 数据库连接方式举例
下面介绍五种连接方式,按从最早的方式到最新的方式排序。事物的发展也必定是从原始到先进的方式去演化的,把前人的路都走一遍,我们能看得更深刻,在未来能飞得更远。
4.1 连接方式一
先来介绍最原始的连接方式。分为 4 个步骤:
- 创建驱动实现类对象
driver
; - 声明数据库 URL ;
- 用 Properties 类的对象封装 MySQL 登录的用户名和密码;
- 最后,调用驱动对象
driver
的方法connect
创建数据库连接对象 Connection 。
- 创建驱动实现类对象
完整代码如下所示:
import com.mysql.jdbc.Driver; import org.junit.Test; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; @Test public void testConnection1() throws Exception { // 1.创建驱动实现类对象 Driver driver = new Driver(); // 2.声明URL String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8"; // 3.封装用户名和密码 Properties info = new Properties(); info.setProperty("user", "root"); info.setProperty("password", "你自己的密码"); // 4.创建Connection连接对象 Connection connect = driver.connect(url, info); // 输出Connection连接对象 System.out.println(connect); }
【注意】
如果出现下面的报错信息:
java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
是因为字符集不一致导致的,则在 URL 的数据库名后加上
?characterEncoding=utf8
即可:jdbc:mysql://localhost:3306/test?characterEncoding=utf8
输出:
com.mysql.jdbc.JDBC4Connection@24273305
这就代表已经成功连接到了我本地的 MySQL 8.0 服务了。
4.2 连接方式二
- 连接方式一有一个缺陷,就是在步骤一中创建驱动对象
driver
时,引入了第三方 MySQL 的驱动 jar 包:com.mysql.jdbc.Driver
。 - 倒不是说不能使用 MySQL 第三方的 API ,而是像方式一这种直接显式地调用第三方 jar 包的API ,会导致代码移植性就会很差。
- 为了解决上述引入第三方 jar 包造成的代码移植性差的问题,就诞生了连接方式二,来对方式一进行迭代。
- 方式二的亮点是利用反射,动态地获取不同数据库 (MySQL 、Oracle、SQLServer、DB2 等) 的驱动实现类对象。从而能够增强了代码的可移植性,能够适应不同厂商的数据库。
- 完整代码如下:
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
@Test
public void testConnection2() throws Exception {
// 1.使用反射获取Driver实现类对象
// 调用Class的静态方法forName(String className)来获取Class实例
Class clazz = Class.forName("com.mysql.jdbc.Driver");
// 调用运行时类的方法newInstance()来创建运行时类的对象,并作强转
Driver driver = (com.mysql.jdbc.Driver) clazz.newInstance();
// 后续代码与方式一相同
// 2.声明数据库URL
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
// 3.使用Properties类封装数据库登录用户名和密码
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "你自己的密码");
// 4.创建Connection连接对象
Connection connect = driver.connect(url, info);
// 输出Connection连接对象
System.out.println("connect = " + connect);
}
输出:
connect = com.mysql.jdbc.JDBC4Connection@24273305
成功连接到了我本地的 MySQL 8.0 服务。
- 第 13 行代码:使用了 17.2.2 中获取 Class 实例的四种方式中的第三种。
- 第 15 行代码:详细见 17.4.1 ,通过运行时类的
newInstance()
方法来创建运行时类的对象。使用该方法的前提条件是该运行时类必须提供空参构造器,且空参构造器的权限必须为 public 。恰好 com.mysql.jdbc.Driver 这个类是满足上述的两个条件的。 - 通过对步骤一的优化,整个代码都没有显式地使用第三方 API ,只是使用了 MySQL 第三方的类的完整包名的 String 字符串 “com.mysql.jdbc.Driver” 来创建反射运行时类。大大增强了代码的可移植性。
4.3 连接方式三
方式二继续往前迭代,就诞生了方式三。方式三的亮点在于:使用了一个 Java 类 java.sql.DriverManager 驱动管理器来获取数据库连接。
在使用 java.sql.DriverManager 获取数据库连接对象之前,我们需要先对驱动进行注册。
// 驱动注册 DriverManager.registerDriver(Driver driver);
java.sql.DriverManager 类下提供了三种获取数据库连接的方法,通常我们使用第二种。
完整代码如下所示:
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
@Test
public void testConnection3() throws Exception {
// 1.反射获取驱动运行时类的对象
Class<?> clazz = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) clazz.newInstance();
// 2.注册驱动
DriverManager.registerDriver(driver);
// 3.声明数据库URL
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
// 4.声明数据库登录用户名和密码
String user = "root";
String password = "你自己的密码";
// 5.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
// 输出连接
System.out.println("connection = " + connection);
}
输出:
connection = com.mysql.jdbc.JDBC4Connection@5b1d2887
成功连接到了我本地的 MySQL 8.0 服务。
4.4 连接方式四
- 方式三继续优化,就是可以省略方式三的步骤二:注册驱动。仅需要保留步骤一:反射获取驱动运行时类的对象。
- 完整代码如下所示:
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
@Test
public void testConnection4() throws Exception {
// 1.声明数据库URL
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
// 2.声明数据库登录用户名和密码
String user = "root";
String password = "你自己的密码";
// 3.反射获取驱动运行时类
Class.forName("com.mysql.jdbc.Driver");
// 4.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
// 输出连接
System.out.println("connection = " + connection);
}
输出:
connection = com.mysql.jdbc.JDBC4Connection@24273305
那为什么可以省略注册驱动的步骤呢?是因为 MySQL 提供的 jar 包已经帮我们把这部分代码实现了。
点开 com.mysql.jdbc.Driver 的源码,可以发现一段这样的静态代码块:
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
第三行代码就是核心, 在 Java SE 中就学过,静态代码块是随着类的加载而执行的,而通过反射就将 Driver 类加载到内存中,同时执行该静态代码块,从而 MySQL 的 Driver 源码已经为我们注册驱动了。
4.5 连接方式五(最终版)
- 方式四还有最后一个弊端,就是步骤一和步骤二的数据库 URL 和数据库登录用户名和密码都直接写死在 Java 程序中。
- 这样做:
- 一是每次更换数据库和更换登录用户都不方便;
- 二是密码直接暴露在代码上不安全。
- 因此,方式五的亮点就是把数据库 URL 和数据库登录用户名和密码写在一个配置文件里,把配置信息与 Java 程序分离开。
- 这样,连接数据库与这些配置信息就可以解耦,只要更改配置文件,就能马上切换到另一个数据库的连接,增强了代码的可靠性和可移植性。
- 还有一个好处,解耦后,如果需要修改配置文件信息,可以避免程序代码重新编译打包,节省部署时间。
- 创建配置文件
在 src 目录右击,新建一个 File,命名为
jdbc.properties
。在该配置文件中写入数据库登录用户名
user
、密码、URL 和 数据库驱动接口全类名。注意此处等号前后绝对不许有空格,否则会造成歧义。user=root password=你自己的密码 url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8 driverClass=com.mysql.jdbc.Driver
- 使用类加载器ClassLoader加载配置文件
- 这部分的内容在 JavaSE 的 17.3.4 中详细讲解过。这是推荐使用的。
- 完整代码如下所示:
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
@Test
public void testConnection5() throws Exception {
// 1.使用类加载器ClassLoader加载配置文件
// ①生成当前运行时类的类加载器对象,通过getClassLoader()方法
ClassLoader classLoader = ConnectionTest.class.getClassLoader();
// ②获取配置文件的输入流,通过类加载器的getResourceAsStream(String name)方法
InputStream is = classLoader.getResourceAsStream("jdbc.properties");
// ③创建Properties类的对象
Properties pros = new Properties();
// ④把配置文件通过输入流载入Properties类的对象中
pros.load(is);
// 2.获取url、用户名和密码,通过Properties类的对象的getProperty(String key)方法
String url = pros.getProperty("url");
String user = pros.getProperty("user");
String password = pros.getProperty("password");
// 3.通过反射获取驱动的运行时类
// ①获取驱动的全类名,通过Properties类的对象的getProperty(String key)方法
String driverClass = pros.getProperty("driverClass");
// ②获取驱动运行时类,通过Class类的forName(String name)方法
Class.forName(driverClass);
// 4.创建连接对象,通过驱动管理器DriverManager的getConnection()方法
Connection connection = DriverManager.getConnection(url, user, password);
// 输出连接
System.out.println("connection = " + connection);
}
输出:
connection = com.mysql.jdbc.JDBC4Connection@5b1d2887
成功连接到了我本地的 MySQL 8.0 服务。这就是获取数据库连接的最终版形态代码。