简介

JDBC用于在Java程序中操作数据库。JDBC提供一套访问各类数据库通用的API,不同的数据库厂商会根据各自的数据库特点去实现这些接口。

JDBC架构

以MySQL为例,需要导入对应版本的jar包才能使用JDBC,如mysql-connector-java-8.0.28.jar下载

基本步骤

  1. 加载驱动(Class.forName)
  2. 建立连接(DriverManager)并返回连接(Connection)
  3. 创建语句对象(Connection 创建一个 Statement 或 PreparedStatement , 用于执行SQL语句)
  4. 执行SQL语句(Statement 或 PreparedStatement执行SQL语句)
  5. 处理结果集(SELECT产生结果集ResultSet)
  6. 关闭连接(依次将ResultSet、Statement、PreparedStatement、Connection对象关闭,释放资源)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.sql.*;

/**
* 我的第一个JDBC程序
*
* @author Joe Zhu
*/
public class JdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 登录
// 默认连接时区为UTC,MySQL可以使用语句"SELECT NOW()"查询当前时间,两者要匹配
String url = "jdbc:mysql://localhost:3306/school?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "root";
// 连接数据库对象
Connection connection = DriverManager.getConnection(url, username, password);
// Statement主要用于执行静态SQL语句
Statement statement = connection.createStatement();
// SQL语句
String sql = "SELECT * FROM student";
// 结果集
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println("number=" + resultSet.getObject("number"));
System.out.println("pwd=" + resultSet.getObject("login_pwd"));
System.out.println("name=" + resultSet.getObject("name"));
}
// 释放连接
resultSet.close();
statement.close();
connection.close();
}
}

设计工具类JDBCUtils

工具类读取配置文件db.properties的内容,连接上数据库。

1
2
3
4
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
* 连接数据库工具类
*
* @author Joe Zhu
*/
public class JDBCUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;

static {
try {
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
// 加载驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}

/**
* 获取连接
*
* @return 数据库连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}

/**
* 释放资源
*/
public static void release(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}

PreparedStatement对象

使用PreparedStatement可防止SQL注入,且执行效率比Statement更高。PreparedStatement是如何防止SQL注入的? - 栖息之鹰 - 博客园

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author Joe Zhu
*/
public class TestSelect {
public static void main(String[] args) throws SQLException {
Connection connection = JDBCUtils.getConnection();
// 预编译SQL
PreparedStatement statement = connection.prepareStatement("select * from `student` where `number`=?");
// 设置参数
statement.setInt(1, 1000);
// 执行
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
System.out.println(resultSet.getString("name"));
}
JDBCUtils.release(connection, statement, resultSet);
}
}