一、概念
引用IBM官网文档的介绍:Java™ database connectivity (JDBC) is the JavaSoft specification of a standard application programming interface (API) that allows Java programs to access database management systems. The JDBC API consists of a set of interfaces and classes written in the Java programming language.
因此,JDBC(Java数据库连接)就是Java程序用于连接数据库的一套标准的API,由一系列的接口与类组成。
二、再理解
理解一个技术,要理解这个技术为什么产生,是解决了当时的什么问题,这样能帮助我们将不断迭代的技术连贯起来。
假想若不存在JDBC,由于市场上有多种关系型数据库(MySQL,ORACLE,DB2等),Java程序想连接不同厂商的数据库,代码层面的实现肯定是不同的。所以对Java程序使用数据库势必是一个麻烦(需要了解Java程序连接不同数据库的实现方式),而且如果需要更换数据库时也会造成不小的影响。因此,如果存在一套API,可以规范化Java访问各种数据库的方式,那将会大大减小切换数据库的成本。基于此,JDBC应运而生了。
上述的概念介绍中提到,JDBC只是一套接口,接口的功能依赖于其实现类。如果你理解了上面一段话,大概能猜想到,这里的实现类就是各个数据库厂商(MySQL,ORACLE,DB2)对JDBC这一套API的具体实现。对于这种实现类,我们称之为驱动(driver)。至此,你是否能够理解maven项目中通常需要引入以下依赖呢?这就是帮助Java程序连接MySQL数据库的JDBC实现类,即MySQL驱动。
XML
<!--MySQL driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
三、示例
JDBC的使用非常简单,代码片段与注释如下:
java
package com.xxx.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 数据库连接地址,注意格式 jdbc:mysql://ip:port/db_name?参数键值对1&参数键值对2
String url = "jdbc:mysql://";
// 数据库用户
String user = "";
// 数据库密码
String password = "";
// 注册驱动,在MySQL5.6之后可以删除
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取数据库连接
Connection connection = DriverManager.getConnection(url, user, password);
// 定义sql
String sql = "update user set phone = '234' where id = 1";
// 获取执行sql的对象
Statement statement = connection.createStatement();
// 执行更新语句
int i = statement.executeUpdate(sql);
// 释放资源
connection.close();
statement.close();
}
}
其中Class.forName(com.mysql.cj.jdbc.Driver)是通过类名加载类,我们点进Driver类发现,当该类一旦被加载时,static代码块就会执行,所以真正加载驱动的逻辑在这里。在MySQL5.6之后,这一行可以去掉了。
java
package com.mysql.cj.jdbc;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
四、多说几句
从上面的代码,可以看到使用JDBC时用到的DriverManager,Connection,Statemement需要引入的包都是java.sql,这意味着这几个类是由Java官方推出的,这正印证了JDBC是一套Java官方定义的一套接口与类这句话。更近一步,点进getConnection, createStatement, executeUpdate方法内部,可以看到都是(或者内部实现调用了)抽象接口。查看这些接口的实现,可以索引到引入的MySQL驱动对这些接口的实现,而这些实现类的导入包,则换成了com.mysql.xxx,即由数据库厂商所实现的。也解完了这些,便对JDBC的概念有了基本的掌握了。
阅读至此,读者可能会有几个问题:
(1)关于JDBC的更多使用细节,业务中常用的增、删、改、查如何用JDBC实现呢?于是,关于JDBC常用的API,可看这篇文章。
(2)获取数据库的连接时需要填入的信息(数据库地址、用户、密码)像以上示例一样写死在代码中,是否不利于维护呢?而且每个请求就重复这个动作是否需要考虑优化?于是,关于数据库连接池,可看这篇文章。
(3)上述示例中,SQL语句与Java代码揉杂在一起并不利于维护,而且返回的结果集只能逐个属性获取,若要封装成一个对象还需要手动set完成,这似乎也是比较繁琐的过程。技术发展如何解决这一问题呢?可看这篇文章关于MyBatis的基本概念。
五、意外情况
如果这里使用的是云服务器,遇到过以下问题。下面的一些思路可估大家参考,与本篇主线不相关。
本机mysql客户端访问云服务器docker容器mysql数据库无法连接的问题解决记录
1、 服务器是否未暴露3306端口:可能未用-p命令将宿主机端口与容器端口进行绑定: 在服务器内部运行: netstat -an | grep 3306
2、防火墙未打开3306端口:firewalld查看防火墙相关
3、数据库权限问题 mysql库user表 select host, user from mysql.user;
4、问题所在:需要在阿里云服务器控制面板放开3306端口限制(华为云是安全组入访规则):所以这里telnet ip 22可以通,但是telnet ip 3306不通。