本文编写于 129 天前,最后修改于 129 天前,其中某些信息可能已经过时。

JDBC 简介

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。

JDBC 架构

JDBC API支持两层和三层处理模型进行数据库访问,但在一般的JDBC体系结构由两层组成:

  • JDBC API: 提供了应用程序对JDBC的管理连接。
  • JDBC Driver API: 支持JDBC管理到驱动器连接。
  • JDBC API的使用驱动程序管理器和数据库特定的驱动程序提供透明的连接到异构数据库。
  • JDBC驱动程序管理器可确保正确的驱动程序来访问每个数据源。该驱动程序管理器能够支持连接到多个异构数据库的多个并发的驱动程序。

以下是JDBC结构图,它显示了驱动程序管理器方面的JDBC驱动程序和Java应用程序的位置:

JDBC 常用API

  • DriverManager

这个类管理数据库驱动程序的列表。确定内容是否符合从Java应用程序使用的通信子协议正确的数据库驱动程序的连接请求。识别JDBC在一定子协议的第一个驱动器将被用来建立数据库连接。

  • Driver

此接口处理与数据库服务器通信。很少直接直接使用驱动程序(Driver)对象,一般使用DriverManager中的对象,它用于管理此类型的对象。它也抽象与驱动程序对象工作相关的详细信息

  • Connection

此接口与接触数据库的所有方法。连接对象表示通信上下文,即,与数据库中的所有的通信是通过此唯一的连接对象。

  • Statement

可以使用这个接口创建的对象的SQL语句提交到数据库。一些派生的接口接受除执行存储过程的参数。

  • ResultSet

这些对象保存从数据库后,执行使用Statement对象的SQL查询中检索数据。它作为一个迭代器,可以通过移动它来检索下一个数据。

  • SQLException

这个类用于处理发生在数据库应用程序中的任何错误。

JDBC 使用步骤

使用JDBC应用程序创建新数据库需要以下步骤:

  • 导入包

需要包含数据库编程所需的JDBC类的包。项目中需要添加数据库连接的jar包才能进行导入。例如:mysql-connector-java-5.1.46.jar。

  • 注册JDBC驱动程序

需要初始化驱动程序,以便可以程序中打开数据库的通信通道。

  • 打开连接

需要使用DriverManager.getConnection()方法来创建一个Connection对象,它表示与数据库服务器的物理连接。要创建一个新的数据库,不需要在准备数据库URL时提供任何数据库名称,如下面的示例所述。

  • 执行查询

需要使用类型为Statement的对象来构建和提交SQL语句到数据库。

  • 清理环境

需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集,避免造成资源的浪费。

JDBC 连接数据库

在执行以下示例之前,请确保您已经准备好以下操作:

具有数据库管理员权限,以在给定模式中创建数据库。 要执行以下示例,需要用实际用户名和密码替换这里用户名(username)和密码(password)。

MySQL或数据库已启动并运行。

准备测试数据

创建测试数据库

CREATE DATABASE easilyj;

创建测试表

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL,
  `user_password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
);

连接数据库

import java.sql.Connection;
import java.sql.DriverManager;
public class CreateDatabase {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    // 获得数据库连接
    public static Connection getConnection() {
        if (null == conn) {
            try {
                Class.forName("com.mysql.jdbc.Driver"); // 加载驱动
                conn = DriverManager.getConnection(url, userName, passWord); // 创建数据库连接
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("JDBC 连接数据库失败");
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        System.out.println("JDBC 连接数据库成功");
        System.out.println("JDBC 连接地址为:" + getConnection());
    }
}

连接成功之后会返回一个获得的连接的内存地址,运行结果:

JDBC 连接数据库成功
JDBC 连接地址为:com.mysql.jdbc.JDBC4Connection@5a10411

JDBC 插入数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class InsertDate {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 准备sql
        String sql = "INSERT INTO user(user_name, user_password) VALUES ('小海绵', '123456')";
        Connection conn = getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            pst.executeUpdate();
            System.out.println("JDBC 插入成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 插入失败");
        }
    }
}

运行结果:

JDBC 插入成功

JDBC 更新数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class UpdateDate {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 准备sql
        String sql = "update user set user_name='大海绵', user_password='654321' where user_id=1";
        Connection conn = getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            pst.executeUpdate();
            System.out.println("JDBC 更新成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 更新失败");
        }
    }
}

运行结果:

JDBC 更新成功

JDBC 查询数据

建议再执行一遍新增,这样数据库就有两条数据,方便观察结果。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SelectDate {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 准备sql
        String sql = "select * from user";
        Connection conn = getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            ResultSet rst = pst.executeQuery();
            while (rst.next()) {
                System.out.print(rst.getInt("user_id"));
                System.out.print(rst.getString("user_name"));
                System.out.println(rst.getString("user_password"));
            }
            System.out.println("JDBC 查询成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 查询失败");
        }
    }
}

运行结果:

1大海绵654321
2小海绵123456
JDBC 查询成功

JDBC 条件查询数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SelectByIdDate {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 准备sql
        String sql = "select * from user where user_id = 1";
        Connection conn = getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            ResultSet rst = pst.executeQuery();
            while (rst.next()) {
                System.out.print(rst.getInt("user_id"));
                System.out.print(rst.getString("user_name"));
                System.out.println(rst.getString("user_password"));
            }
            System.out.println("JDBC 条件查询成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 条件查询失败");
        }
    }
}

运行结果:

1大海绵654321
JDBC 条件查询成功

JDBC 删除数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DeleteDate {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 准备sql
        String sql = "delete from user where user_id = 2";
        Connection conn = getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            pst.executeUpdate();
            System.out.println("JDBC 删除成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 删除失败");
        }
    }
}

运行结果:

JDBC 删除成功

JDBC 工具类

经过上面的学习,会发现增删改查都有很多共同点,不同之处只是SQL语句和接收返回值的方式不同,那么为了使程序的复用性更好,我们通常把相同的代码提取出来。下面的代码演示一个通过提取出来的工具类进行新增操作。

DBUtil工具类

import java.sql.Connection;
import java.sql.DriverManager;
public class DBUtil {
    private static String url = "jdbc:mysql://localhost:3306/easilyj"; // 数据库地址
    private static String userName = "root"; // 数据库用户名
    private static String passWord = "123456"; // 数据库密码
    private static Connection conn = null;
    public static Connection getConnection() {
        if (null == conn) {
            try {
                // 加载驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 创建数据库连接
                conn = DriverManager.getConnection(url, userName, passWord);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }
    public static void main(String[] args) {
        // 测试数据库是否连通
        System.out.println(getConnection());
    }
}

新增数据改为以下代码:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class InsertDate {
    public static void main(String[] args) {
        // 准备sql
        String sql = "INSERT INTO user(user_name, user_password) VALUES ('小海绵', '123456')";
        Connection conn = DBUtil.getConnection();
        PreparedStatement pst = null;
        try {
            // 创建预编译语句
            pst = conn.prepareStatement(sql);
            // 执行SQL
            pst.executeUpdate();
            System.out.println("JDBC 插入成功");
            // 关闭资源
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("JDBC 插入失败");
        }
    }
}

同样的,可以将增删改查都改成这种方式,使代码更加的简洁,更具有逻辑性和复用性。