本文使用数据库为Mysql 8+版本
1. JDBC是什么
JDBC 的全称是(Java Database Connectivity),即Java数据库连接。
简单来说,就是一组用于执行Sql语句的Java API。
2. 导入Mysql驱动的jar包

我们建立一个标准的Java Web项目,
在WEB-INF下面建立一个package并且命名为
lib
将
mysql-connector-java-8.0.19.jar
复制到lib
(不要写成libs!!!)包下面导入jar包到library中
- 右键lib
- 选中
Add as Library
- 点击
OK

3. JDBC常见的使用流程
在导完jar包后,想使用jdbc主要有以下几个流程
- 注册Driver
- 建立Connection
- 获取Statement
- 使用Statement执行sql语句,并获取RestultSet
- 操作获取的ResultSet
- 关闭连接
这就是一般JDBC的使用流程,大家可以先有个概念,接下来我会逐个进行讲解。
4. 快速上手JDBC
首先,我们快速建立一个用于测试的表
这是sql语句,大家直接复制粘贴就行
create database if not exists jdbc_demo
use jdbc_demo
create table user
(
id bigint auto_increment,
username varchar(64) not null comment '帐号',
password varchar(64) not null comment '密码',
constraint user_pk
primary key (id)
)
comment '用户表';
INSERT INTO jdbc_demo.user (username, password) VALUES ('user1', '123')
INSERT INTO jdbc_demo.user (username, password) VALUES ('user2', '456')
INSERT INTO jdbc_demo.user (username, password) VALUES ('user3', '123456')
我们先分步讲解,最后进行汇总,尽量通俗易懂。
前两部分内容会比较多,后面较少
我们新建一个MyJDBCDemo1.java
,并进入Main
方法
4.1 注册Driver
首先,我们来注册Driver
,点开Driver
的源码,我们可以看到其中的文档写着(这个是IDEA 2020+版本的新特色,可以预览JavaDoc文档)

一句话总结:当一个Driver 类被加载,需要创建自己的实例并且注册到
DriverManager
中
那么,我们就先加载Driver类。
使用Class.forName
加载 driver
,该方法是用来加载类(.class)文件。
Classs.forName("com.mysql.cj.jdbc.Driver")
当一个类被加载时,会执行其中的静态代码块
我们点开driver
的源码可以发现:
在第 9 行,这个driver
被注册到了DriverManager
。
package com.mysql.cj.jdbc;
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!");
}
}
}
而registerDriver
方法的注释写着,该方法会将driver注册到driverManager中

而DriverManager
又是什么呢?
我们进一步点开DriverManager
的源码,可以看到其中java doc 文档中的第一行写着
The basic service for managing a set of JDBC drivers
也就是说,它是用来管理一系列JDBC 驱动的,因为不只是Mysql,也有Oracle、SqlServer等等。
小坑:
com.mysql.cj.driver
是Mysql8+版本使用的
如果是Mysql5+的话,使用com.mysql.jdbc.driver
4.2 建立Connection
注册好driver之后,我们来建立Connection
// 先定义好获取Connection需要的属性
// 这个Mysql url 大家随机应变,记住mysql8+要加入时区serverTimezone
public static final String JDBC_MYSQL_URL = "jdbc:mysql://localhost:3306/jdbc_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF8&useSSL=false";
public static final String USER = "root";
public static final String PASSWORD = "123456";
// 2. 建立Connection
Connection connection = DriverManager.getConnection(JDBC_MYSQL_URL, USER, PASSWORD);
DriverManager.getConnection()
该方法中有三个参数:

- url——数据库url
- 数据库用户名
- 数据库密码
4.3 获取Statement
利用我们刚刚建立的Connection获取Statement
Statement
可以用来执行我们的sql语句
还有一个可以配合占位符使用的PrepareStatement
,我们下面会简单介绍使用
// 3. 获取Statement
Statement statement = connection.createStatement();
4.4 使用Statement执行sql语句,并获取RestultSet
// 4. 编写Sql,并执行
// 这里面打sql
String sql = "select count(*) from jdbc_demo.user";
ResultSet resultSet = statement.executeQuery(sql);
// 这里建议大家先定义String sql = "";
// 然后写下一行代码,再补全sql字符串,因为这样写sql语句会有提示。
4.5 操作获取的ResultSet
// 5. 操作结果集ResultSet
// 如果结果集还有数据
while (resultSet.next()) {
// 进行操作
String username = resultSet.getString("username");
System.out.println(username);
}
我们来一起看下控制台的输出结果

当当当!!!
是不是拿到数据库的数据了!是不是感觉很神奇哈哈哈 😀
4.6 关闭连接,释放资源
我们按照建立 Connection、Statement、ResultSet的倒序进行关闭
resultSet.close();
statement.close();
connection.close();
到这里我们的快速上手就结束啦!
已经可以初步使用JDBC连接数据库啦~~
完整DEMO代码
public class MyJDBCDemo1 {
public static final String JDBC_MYSQL_URL = "jdbc:mysql://localhost:3306/jdbc_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF8&useSSL=false";
public static final String USER = "root";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1. 注册driver
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立Connection
Connection connection = DriverManager.getConnection(JDBC_MYSQL_URL, USER, PASSWORD);
// 3. 获取Statement
Statement statement = connection.createStatement();
// 4. 编写Sql,并执行
String sql = "select * from jdbc_demo.user";
ResultSet resultSet = statement.executeQuery(sql);
// 5. 操作结果集ResultSet
while (resultSet.next()) {
String username = resultSet.getString("username");
System.out.println(username);
}
// 6. 关闭连接,释放资源
// 我们按照建立 Connection、Statement、ResultSet的倒序进行关闭
resultSet.close();
statement.close();
connection.close();
}
}
接下来我们介绍下JDBC常见的API使用
5. JDBC 常见CRUD API介绍
刚刚上面我们是使用sql的查询语句。
这部分我们简单介绍下JDBC的CRUD API,大家只需要替换下第 4、5 部分就可以
C——创建
除了select
,我们都会使用statement
的excuteUpdate
方法
这里id 写成 null,是因为我们数据库设置了自增,所以不需要id,当然自己指定也是可以的
// 4. 编写Sql,并执行
String sql = "insert into jdbc_demo.user values(null,'user4','123456')";
int i = statement.executeUpdate(sql);
// 5. 获取结果,输出1说明成功。
System.out.println(i);
我们看到控制台的确输出1
,并且数据库的确有新纪录。


R——读取
我们在4.5中使用了executeQuery
,使用了getString
,这个是获取字符串,如果大家想要获取int等等,使用getInt(“字段名”)等等即可
U——更新
// 4. 编写Sql,并执行
String sql = "update jdbc_demo.user set username = 'userUpdated' where username = 'user4'";
int i = statement.executeUpdate(sql);
// 5. 获取结果
System.out.println(i);
基本验证也是和create
部分一样,我们直接看数据库是否进行了更新

我们可以看到刚刚的第四条记录已经被正确更新了。
但是,大家看到这里,可能有一个疑问:你这里的sql语句是写死的,万一我的条件是动态的怎么 办呢?
没错,如果这样写死sql语句,的确会有很多问题。
大家还记得上面说的PrepareStatement
吗?我们下一部分会介绍使用用它来解决这个问题。
D——删除
// 4. 编写Sql,并执行
String sql = "delete from jdbc_demo.user where username = 'userUpdated'";
int i = statement.executeUpdate(sql);
// 5. 获取结果
System.out.println(i);
我们来直接看数据库结果

可以发现确实第四条记录被删除了。
接下来我们就介绍以下PrepareStatement
的使用。
6. PreparedStatement
PrepardStatement
可以解决sql语句被写死的问题
还记得我们上面使用Statement
的顺序吗,我们是利用connection
直接建立。
而PreparedStatement
的使用则有一些不同
- 我们需要先写sql语句
- 然后直接利用connection获取preparedStatement并装配sql语句
// 3. 编写Sql(?就是占位符)
String sql = "delete from jdbc_demo.user where username = ?";
// 4. 获取PreparedStatement
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 5. 设置占位符(这里index是从1开始,不是从0!!!)
preparedStatement.setString(1, "user1");
// 6. 执行
int i = preparedStatement.executeUpdate();
// 7. 输出结果
System.out.println(i);
我们来看下数据库的结果

我们可以看到user1
的确被删除了。
平常如果是要做登录案例什么的,就可以使用PreparedStatement
7. 封装简单的JDBC工具类
看完上面的内容,大家可能还是有疑惑,我难道每使用一次statement,都要写属性,创建连接,释放连接,这么麻烦吗?
为了解决刚刚说的问题,我们可以封装一个简单的工具类,让我们更加专注于编写业务逻辑。
这是工具类的代码,大家简单看下,直接复制就可以。
这里获取属性没有使用Properties文件,大家可以根据自己需要,自行修改
package utils;
import java.sql.*;
/**
* @author Lemonfish
* @version V1.0
* @Package utils
* @date 2020/5/14 10:29
*/
public class JDBCUtil {
/**
* 数据库URL
*/
public static final String JDBC_MYSQL_URL = "jdbc:mysql://localhost:3306/jdbc_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF8&useSSL=false";
/**
* 数据库帐号
*/
public static final String USER = "root";
/**
* 数据库密码
*/
public static final String PASSWORD = "123456";
// 静态代码块,用于初始化
static {
// 注册driver
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取Connection
* @return Connection
*/
public static Connection getConnection(){
Connection connection = null;
try {
// 建立Connection
connection = DriverManager.getConnection(JDBC_MYSQL_URL, USER, PASSWORD);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
/**
* @Description 关闭全部
* @param connection connection
* @param statement statement
* @param resultSet resultSet
* @return void
*/
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
closeResultSet(resultSet);
closeStatement(statement);
closeConnection(connection);
}
/**
* @Description 除了ResultSet,关闭其他全部
* @param connection connection
* @param statement statement
* @return void
*/
public static void closeWithoutResultSet(Connection connection, Statement statement) {
closeStatement(statement);
closeConnection(connection);
}
/**
* @Description 关闭Connection
* @param connection connection
* @return void
*/
public static void closeConnection(Connection connection) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
/**
* @Description 关闭Statement
* @param statement statement
* @return void
*/
public static void closeStatement(Statement statement) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
/**
* @Description 关闭ResultSet
* @param resultSet resultSet
* @return void
*/
public static void closeResultSet(ResultSet resultSet) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
接下来,我们使用刚刚封装的工具类,看看效果怎么样
public class MyJDBCDemo6 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
// 1.获取连接
Connection connection = JDBCUtil.getConnection();
// 2.获取statement
Statement statement = connection.createStatement();
// 3. 编写Sql,并执行
String sql = "delete from jdbc_demo.user where username = 'user3'";
// 4 执行
int i = statement.executeUpdate(sql);
// 5. 输出结果
System.out.println(i);
// 6. 断开连接
JDBCUtil.closeWithoutResultSet(connection,statement);
}
}
这样代码是不是看起来会清爽很多?OvO
我们来看下数据库的结果,可以发现user2
确实被删掉了。

8. 写在最后
本文就到这里结束啦~
简单介绍了一些JDBC的使用方法,但是JDBC还有其他内容,大家可以自己探索。
如果想要获取实体类对象的话,可以使用commons-dbutils
的QueryRunner
再往后使用框架会更加方便,比如Spring Data Jpa
/ Mybatis
(建议配合Mybatis-Plus
使用)
如果觉得对你有帮助的话,欢迎点个👍赞喔,谢谢支持!
希望大家能一起进步~~