JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发者能够编写数据库的程序。
简单地说,JDBC 可做三件事:
安装好数据库之后,编写后应用程序也不能直接操作数据库的,必须要通过JDBC驱动管理器加载相应数据库的驱动程序,才能与数据库连接,然后访问数据库。数据库驱动是不同数据库开发商(比如oracle mysql等)为了某一种开发语言环境(比如Java)能够实现统一的数据库调用而开发的一个程序。例如数据库开发商根据JDBC提供的API来编写实现访问数据库的程序。
Java应用程序访问数据库的一般过程如下图所示:
 
有的数据库管理系统安装后就安装了JDBC驱动程序(如Oracle数据库),这时只需将驱动程序文件添加到CLASSPATH环境变量中即可。像MySQL、PostgreSQL等数据库需要单独下载驱动程序。
SQL Server数据库驱动程序下载地址:https://docs.microsoft.com/zh-cn/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-ver15
MySQL数据库驱动程序下载地址:https://dev.mysql.com/downloads/connector/j/ ,选择操作系统时,window系统的用户选择Platform Independent。
JDBC API在JDK中是通过java.sql和java.xsql两个包提供的。
Driver接口
? 用于加载JDBC驱动程序必须实现的接口,在编写JDBC的时候,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中
DriverManager类
? 用于加载JDBC驱动并且创建于数据库的连接。在该类中,定义了两个比较重要的静态方法。
| 方法名称 | 功能描述 | 
|---|---|
| registerDriver(Driver driver) | 该方法用于向DriverManager中注册给定的JDBC驱动程序 | 
| getConnection(String url,String user,String pwd) | 该方法用于建立和数据库的连接,并返回表示连接的Connection对象 | 
? 代表Java程序与数据库的连接,只有获得该连接对象后才能访问数据库。常用的方法有
| 方法名称 | 功能描述 | 
|---|---|
| getMetaData() | 该方法同于返回表示数据库的元数据的 DatabaseMetaData对象 | 
| createStatement() | 用于创建一个Statement对象并将SQL语句发送导数据库 | 
| prepareStatement(String sql) | 用于创建一个PreparedStatement对象并将参数化的SQL语句发送到数据库 | 
| prepareCall(String sql) | 用于创建一个CallableStatement对象来调用数据库的存储过程 | 
? 用于执行静态的SQL语句,并返回一个结果对象。该接口的对象通过Connection实例的createStatement()方法获得。常用的方法有
| 方法名称 | 功能描述 | 
|---|---|
| execute(String sql) | 用于执行各种SQL语句,该方法返回一个boolean类型的值,如果为true,表示所执行的SQL语句有查询结果,可通过Statement的getResultSet()方法获得查询结果 | 
| executeUpdate(String sql) | 用于执行SQL语句中的INSERT、UPDATE和DELETE语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录条数 | 
| executeQuery(String sql) | 用于执行SQL语句中的SELECT语句,该方法返回一个表示查询结果的ResultSet对象 | 
? 是Statement的子接口,用于执行预编译的SQL语句。该接口扩展了带有参数SQL语句的执行操作,引用该接口中的SQL语句可以使用占位符“?”来代替其参数,然后通过setXxx()方法为SQL语句的参数赋值。常用的方法有
| 方法名称 | 功能描述 | 
|---|---|
| executeUpdate() | 在此PreparedStatement对象中执行SQL语句,该语句必须是一个DML语句或者是无返回内容的SQL语句,比如DDL语句 | 
| executeQuery() | 在此PreparedStatement对象中执行SQL语句,该方法返回的是ResultSet对象 | 
| setInt(int parameterIndex,int x) | 将指定参数设置为给定的int值 | 
| setFloat(int parameterIndex,float x) | 将指定参数设置为给定的float值 | 
| setString(int parameterIndex,String x) | 将指定参数设置为给定的String值 | 
| setDate(int parameterIndex,Date x) | 将指定参数设置为给定的Date值 | 
| addBatch() | 将一组参数添加到此PreparedStatement对象的批处理命令中 | 
| setCharacterStream(int parameterIndex,java.io.Reader reader,int length) | 将指定的输入流写入数据库的文本字段 | 
| setBinaryStream(int parameterIndex,java.io.InputStream x,int length) | 将二进制输入流数据写入到二进制字段中 | 
注意:setDate()方法可以设置日期内容,但参数Date的类型是java.sql.Date,而不是java.util.Date
? 用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中。在ResultSet接口内部有一个指向表格数据航的游标(或指针),ResultSet对象初始化的时候,游标在表格的第1行之前,调用next()方法可将游标移动到下一行。如果下一行没有数据,则返回false。常用的方法有
| 方法名称 | 功能描述 | 
|---|---|
| getString(int columnIndex) | 用于获取指定字段的String类型的值,参数columnIndex代表字段的索引 | 
| getString(String columnName) | 用于获取指定字段的String类型的值,参数columnName代表字段的名称 | 
| getInt(int columnIndex) | 用于获取指定字段的int类型的值,参数columnIndex代表字段的索引 | 
| getInt(String columnName) | 用于获取指定字段的int类型的值,参数columnName代表字段的名称 | 
| getDate(int columnIndex) | 用于获取指定字段的Date类型的值,参数columnIndex代表字段的索引 | 
| getDate(String columnName) | 用于获取指定字段的Date类型的值,参数columnName代表字段的名称 | 
| next() | 将游标从当前位置向下移一行 | 
| absolute(int row) | 将游标移动到此ResultSet对象的指定行 | 
| afterLast() | 将游标移动到此ResultSet对象的末尾,即最后一行之后 | 
| beforeFirst() | 将游标移动到此ResultSet对象的开头,即第一行之前 | 
| privious() | 将游标移动到此ResultSet对象的上一行 | 
| last() | 将游标移动到此ResultSet对象的最后一行 | 
使用JDBC API连接和访问数据库,一般分为一下5个步骤:
下面详细叙述这些步骤。
? 加载驱动程序一般使用Class类的forName()静态方法,格式如下:
public static Class<?> forName(String className)
? 该方法返回一个Class类的对象。参数className为字符串表示的完整驱动程序类的名称,若找不到驱动程序将抛出ClassNotFoundException异常。
? 对于不同的数据库,驱动程序的类名不同。下面几行代码分别是加载MySQL数据库、Oracle数据库和SQL Server数据库的驱动程序:
// 加载MySQL数据库驱动程序
Class.forName("com.mysql.jdbc.Driver");
// 加载Oracle数据库驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
// 加载SQL Server数据库驱动程序
Class.forName("com.micrsoft.jdbc.sqlserver.SQLServerDriver");
DriverManager类
DriverManager类是JDBC的管理层,作用于应用程序和驱动程序之间。建立数据库连接的方法是调用DriverManager类的getConnection()静态方法,该方法有下面两种格式:
public static Connection getConnection(String dburl);
public static Connection getConnection(String dburl,String user,String password);
参数dburl表示JDBC URL,user表示数据库用户名,password表示口令。
数据库URL
数据库URL与一般的URL不同,用来标识数据源。数据库URL的标准语法如下:
?				jdbc:
下面代码建立了一个到MySQL数据库的连接:
private String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
 Connection conn = DriverManager.getConnection(url, "root", "123456");
? 上述代码中,localhost表示本机,也可以使用IP地址127.0.0.1;3306为MySQL数据库服务器使用的默认端口号;要使用的数据库名为test;用户名为root;口令为123456.
? 常用数据库JDBC连接代码:
/*
 Oracle数据库
*/
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","root","123456");  // orcl为数据库的SID  
/*
 MySQL数据库
 
// serverTimezone可以设置为北京时间GMT%2B8、上海时间Asia/Shanghai或者香港时间Hongkong
url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
*/
Class.forName("com.mysql.cj.jdbc.Driver");	//mysql 8.0版本使用
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName","root","123456");  //MySQL 8.0版本的URL还应设置时区
/*
 SQL Server数据库
*/
Class.for.Name("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://dbServerIP:1433;databaseName=master","root","123456");
/*
 PostgreSQL数据库
*/
Class.forName("org.postgresql.Driver");
Connection conn=DriverManager.getConnection("jdbc:postgresql://dbServerIP/dbName","root","123456");
MySQL的数据库URL设置为
jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
Connection对象
? SQL语句对象有3种:Statement、PreparedStatement和CallbleStatement。通过调用Connection接口的相应方法可以得到这3种语句对象。
Statement对象详解 JDBC 常用API的Statement接口
PreparedStatement对象详解 JDBC 常用API的PreparedStatement接口
ResultSet对象表示SQL查询语句得到的记录集合,称为结果集。结果集一般是一个记录表,其中包含列标题和多个记录行,一个Statement对象或一个PreparedStatement对象一个时刻只能打开一个ResultSet对象。
ResultSet对象使用方法可参考查看 JDBC 常用API的ResultSet接口
数据库访问结束后,应该关闭有关对象,以释放资源。可以使用每种对象的close()方法关闭对象。
创建数据库和数据表
? SQL语句如下:
-- 创建数据库test
CREATE DATABASE test;
-- 使用刚创建的数据库test
USE test;
-- 创建user表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
 -- 插入数据
INSERT INTO `user` VALUES (1, ‘杨小强‘, ‘123456‘);
INSERT INTO `user` VALUES (2, ‘李华‘, ‘654321‘);
创建java项目
? 将MySQL数据库驱动程序的jar文件导入到项目依赖中
package mysql;
import java.sql.*;
/**
 * @Author: XQ-Yang
 * @Date: 2021/5/15
 * @Tools: IntelliJ IDEA
 * @Remember: Be professional every day
 **/
public class MySQLDemo {
    public static void main(String[] args) throws SQLException {
        // 加载驱动,如果数据库驱动程序的jar包放在了项目的依赖文件夹下,可以不用写,称之为动态加载驱动程序
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 数据库URL、用户名、密码、sql语句
        String dburl = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String password = "yxq";
        String sql = "select * from user";
        // 初始化要用到的对象,使作用域能作用到关闭资源
        Connection conn = null;
        Statement st = null;
        ResultSet rst = null;
        try {
            // 获取连接
            conn = DriverManager.getConnection(dburl, username, password);
            // 获取Statement对象
            st = conn.createStatement();
            // 获得结果集
            rst = st.executeQuery(sql);
            // 遍历结果集
            System.out.println("id\tuser\tpassword");
            while (rst.next()){
                System.out.println(rst.getInt(1)+"\t"+rst.getString(2)+"\t"+rst.getString(3));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            // 关闭资源
            rst.close();
            st.close();
            conn.close();
        }
    }
}
执行结果如下图:

? 既然Java是面向对象语言,面向对象的核心思想就是对象,那么应该将这些代码封装起来。封装过程及演示请参考博客园文章:
使用JDBC实现mysql数据库的增删查改:https://www.cnblogs.com/XQ-Yang/p/14686807.html
原文:https://www.cnblogs.com/XQ-Yang/p/14839044.html