【JavaEE基础学习打卡05】JDBC之基本入门就可以了

news2025/4/16 14:00:05

目录

  • 前言
  • 一、JDBC学习前说明
    • 1.Java SE中JDBC
    • 2.JDBC版本
  • 二、JDBC基本概念
    • 1.JDBC原理
    • 2.JDBC组件
  • 三、JDBC基本编程步骤
    • 1.JDBC操作的数据库准备
    • 2.JDBC操作数据库表步骤
  • 四、代码优化
    • 1.简单优化
    • 2.with-resources探讨
  • 总结


前言

📜 本系列教程适用于JavaWeb初学者、爱好者,小白白。我们的天赋并不高,可贵在努力,坚持不放弃。坚信量最终引发质变,厚积薄发。
🚀 文中白话居多,尽量以小白视角呈现,帮助大家快速入门。
🎅 我是 蜗牛老师,之前网名是 Ongoing蜗牛,人如其名,干啥都慢,所以更新也慢。希望大家多多支持,让我动力十足!

本文主要讲述 JDBC 编程基本步骤,带领大家基本入门,通过 JDBC API 实现与数据库连接,并简单查询数据库表中的数据到 Java 中。但是总想把知识点的前前后后都说清楚,所以整体篇幅有点长。


一、JDBC学习前说明

1.Java SE中JDBC

大家还记得我们说过 Java EE 中有 JDBC API,我们一起再回顾一下。

Java 数据库连接 API
Java 数据库连接(JDBC) API 允许从Java编程语言方法调用 SQL 命令。当使用会话 Bean 访问数据库时,可以在企业 Bean 中使用 JDBC API。还可以使用来自 Servlet 或 JSP 页面的 JDBC API 直接访问数据库,而无需通过企业 Bean。

JDBC API 有两个部分:

  • 应用程序组件用来访问数据库的应用程序级接口
  • 将 JDBC 驱动程序附加到 Java EE 平台的服务提供程序接口

Java EE 8 平台需要 JDBC 4.1。

Java EE 中的 JDBC API 其实是 Java SE 中集成库中的 API,JDBC API 由两个包组成:

  • java.sql
  • javax.sql

当我们下载 Java 平台标准版(Java SE) 时,将自动获得这两个包。

2.JDBC版本

Java EE 8 平台需要 JDBC 4.1。那么 JDBC 4.1 其实是 Java SE 7 版本中增强的内容。

Java SE7 中 JDBC 4.1 引入了以下特性:

  • 使用 try-with-resources 语句自动关闭 ConnectionResultSetstatement 类型的资源的能力。
  • RowSet 1.1:引入 RowSetFactory 接口和 RowSetProvider 类,它们能够创建 JDBC 驱动程序支持的所有类型的行集。

Java SE8 中 JDBC 4.2 引入了以下特性:

  • 增加了对 REF_CURSOR 的支持。
  • 增加了 java.sql.DriverAction 接口。
  • DriverManager 类中增加了对 deregisterDriver 方法的安全检查。
  • 新增 java.sql.SQLType 接口。
  • 增加 java.sql.JDBCType 枚举。
  • 增加对大更新计数的支持。
  • 对现有接口的更改。
  • Rowset 1.2:列出 JDBC Rowset 的增强。

大家也看到了,Java EE 8 使用的是 Java SE 7 中 JDBC 4.1,而 Java SE 8 中的 JDBC 版本是4.2,对于Java SE 9 中的 JDBC 版本是4.3,每个 JDBC 版本都有功能的增强,但是对于目前的我们来说,这些新增的特性没必要学习,我们需要是对 JDBC 有个基本入门即可。因为日后几乎不会使用原始的 JDBC 进行编程,它仅仅是我们学习持久层框架的基础而已,因为这些框架的底层就是 JDBC API。

二、JDBC基本概念

Java Database Connectivity,Java 数据库连接(Database 数据库,Connectivity 连通、联接),简称 JDBC。是 Java 应用程序与各种数据库和数据源之间连接的 API(Application Programming Interface,应用程序编程接口)。

Java 数据库连接(JDBC) API 提供了来自 Java 编程语言的通用数据访问。使用 JDBC API,几乎可以访问任何数据源,可以使用基本的 JDBC API 来创建表、向表中插入值、查询表、检索查询结果以及更新表。

1.JDBC原理

其实我们知道即使是关系型数据库,市面上也有很多种,比如 MySQL、Oracle 等,JDBC API 如何做到通用呢?也就是说如何做到访问不同的数据库呢?

其实要在特定的数据库管理系统中使用 JDBC API,需要一个基于 JDBC 技术的驱动程序来在 JDBC 技术和数据库之间进行中介。根据各种因素,驱动程序可以完全用 Java 编程语言编写,也可以混合使用 Java 编程语言和 Java 本机接口(Java Native Interface, JNI)本地方法编写。

简单理解就是 JDBC API 是 Java 程序连接数据库的标准接口,具体说各个数据库想要通过 Java 编程使用,就需要由各个数据库厂商自己按照 JDBC 标准提供具体实现。

来一张图进行说明吧

在这里插入图片描述
JDBC 为多种关系数据库提供了统一访问方式,作为特定厂商数据库访问 API 的一种高级抽象,它主要包含一些通用的接口类。然后各厂商提供自己的 JDBC 实现,也就是 JDBC 驱动程序。最后程序员就可以通过 JDBC 驱动程序实现该数据库的操作了。

2.JDBC组件

这里简单介绍一下 JDBC 组件,大家了解即可。

JDBC 包括四个组件:

  • JDBC API: JDBC API 提供了对 Java 编程语言中的关系数据的编程访问。使用 JDBC API,应用程序可以执行 SQL 语句、检索结果并将更改传播回底层数据源。JDBC API 还可以与分布式异构环境中的多个数据源进行交互。JDBC API 是 Java 平台的一部分,该平台包括 Java 标准版(Java SE)和 Java 企业版(Java EE)。JDBC API 两个包:java.sqljavax.sql。这两个包都包含在 Java SE 和 Java EE 平台中。
  • JDBC 驱动管理器: JDBC 驱动管理器类定义了可以将 Java 应用程序连接到 JDBC 驱动程序的对象。传统上,DriverManager 一直是 JDBC 体系结构的支柱。它是相当小和简单。
  • JDBC 测试套件: JDBC 驱动程序测试套件帮助确定 JDBC 驱动程序将运行的程序。这些测试并不全面或详尽,但它们确实测试了 JDBC API 中的许多重要特性。
  • JDBC-ODBC桥: Java 软件桥通过 ODBC 驱动程序提供 JDBC 访问。注意,需要将 ODBC 二进制代码加载到使用该驱动程序的每台客户机上。因此,ODBC 驱动程序最适合于客户端安装不是主要问题的企业网络,或者适合于用 Java 在三层体系结构中编写的应用程序服务器代码。

三、JDBC基本编程步骤

前面大家尽量理解就好,本章节就是重点了,我们要使用 JDBC 进行实操了。

JDBC 帮助可以编写管理以下三种编程活动的 Java 应用程序:

  1. 连接到数据源,如数据库。
  2. 向数据库发送查询和更新语句。
  3. 检索并处理从数据库接收到的结果。

JDBC 可以做的这三件事,就是 JDBC 编程的大致操作步骤。

1.JDBC操作的数据库准备

我们打开客户端 MySQL Workbench,连接到本地 MySQL 服务器。接下来图形界面操作起来吧。

创建数据库 test_jdbc
在这里插入图片描述

数据库中创建 teacher

在这里插入图片描述

teacher 表中添加数据,点击图中红色框中的图标,在数据界面添加数据。

在这里插入图片描述

2.JDBC操作数据库表步骤

打开 IDEA,创建一个普通的 Java 项目。

在这里插入图片描述

src 下新建 Test 类,生成主函数 main() 方法

在这里插入图片描述

做好以上准备后,我们来看 JDBC 详细编程步骤:

  1. 引入驱动并加载
  2. 建立数据库连接
  3. 创建语句对象
  4. 执行SQL语句并返回结果
  5. 处理结果
  6. 关闭资源

我们看具体演示:

第一步:将数据库驱动程序引入到项目,并在程序中加载

JDBC 驱动程序是由数据库厂商提供的,这里使用了 MySQL 数据库,所以我们可以到 MySQL 官网下载该驱动,也就是一个 jar 包。

下载步骤大家可以参考这篇文章:https://blog.csdn.net/Li_Ya_Fei/article/details/104583417

我本地的 MySQL 版本是8.0.30,所以从官网下载了对应版本的驱动 jar包。下载后的 jar包如下图所示:

在这里插入图片描述
test-jdbc 项目中新建 lib 文件夹(习惯性将 jar 包统一放在此文件夹管理,lib 也就代表 Library,库),将 jar 包复制进来,这时该 jar 只是放在了 lib 文件夹下,并没有引入到项目中,需要选中 jar 包右键,在菜单中点击 Add as Library...,将其添加了项目库中。

在这里插入图片描述
添加后,是可以查看其源代码的。

在这里插入图片描述

将 MySQL 数据库驱动引入到项目后,如何在程序中加载呢?

我们使用 Class.forName(‘驱动路径’) 去动态加载 MySQL 的 JDBC 驱动实现。它的作用是加载指定路径下的 MySQL JDBC 驱动,并将其注册到 DriverManager 中,以便后续的数据库连接操作可以使用该驱动。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的 MySQL JDBC驱动,将其注册到 DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出 ClassNotFoundException异常。
        e.printStackTrace();
    }
}

需要注意的是,这段代码必须在其他数据库操作之前执行,以确保在使用其他数据库操作之前已经正确加载了 MySQL 的 JDBC 驱动。如果该驱动类不存在或无法被加载,则会抛出 ClassNotFoundException 异常,打印异常堆栈信息。

这里只需要记住 MySQL JDBC 驱动的位置是 com.mysql.cj.jdbc.Driver。我们可以直接找到该类。

在这里插入图片描述

我们顺便看一眼源码,其实还挺简单的。

它定义了一个名为 Driver 的类,该类继承自 NonRegisteringDriver 并实现了 java.sql.Driver 接口。足以说明该类是 JDBC API 的一个实现。在静态代码块中,尝试使用 DriverManager.registerDriver() 方法注册这个驱动。如果注册失败,将抛出一个运行时异常。

第二步:建立 JDBC 和数据库之前的 Connection 连接

上一步将 MySQL JDBC 驱动注册到 DriverManager,从字面我们知道DriverManager 就是驱动的管理器,管理诸多驱动程序。所以我们建立与数据库的连接,要从 DriverManager 获得。使用DriverManager.getConnection(‘连接信息’),方法中需要填写连接信息,我们使用客户端也需要先填写连接信息才能操作数据库,这里也是一样的,也需要有连接信息,才能连接到数据库。

我们先上代码,然后再解释说明。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的 MySQL JDBC驱动,将其注册到 DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库 URL的连接。
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");

    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出 ClassNotFoundException异常。
        e.printStackTrace();
    } catch (SQLException throwables) {
        // ②如果数据库访问错误发生或 url为空时,会抛出 SQLException异常。
        throwables.printStackTrace();
    }
}

在上述代码中,②处用于建立到 MySQL 数据库的连接,它使用了DriverManager.getConnection() 方法来获取一个与指定 URL 相对应的数据库连接对象。该方法有 SQLException 这个异常需要处理。在代码中,DriverManager.getConnection() 方法接受三个参数:

  • 第一个参数是数据库的 URL,指定了要连接的数据库的位置和端口号。在这个例子中,URL 为 jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai,表示连接到本地主机(127.0.0.1)的 MySQL 服务器上,端口号为3306,数据库名为 test_jdbc,并设置了时区为 Asia/Shanghai。注意,不设置时区是会报错的哦!
  • 第二个参数是用于连接数据库的用户名,这里设置为"root"。
  • 第三个参数是用于连接数据库的密码,这里也设置为"root"。数据库密码是我们安装 MySQL 服务器时设置的密码哦。

该方法返回 Connection 对象,我们接收一下就可以,Connection 对象就是与 MySQL 数据库的连接(会话)。我们可以在连接的上下文中执行 SQL 语句并返回结果。

这里大家其实需要注意 MySQL 数据库 URL 的写法,虽然现在网上查询 URL 很方便,但是自己能记忆最好。

第三步:创建 Statement 对象,用于向数据库发送 SQL 语句

这里使用 Connection 连接对象中的 createStatement() 方法创建 Statement 语句对象,用于向数据库发送 SQL 语句。Statement 用于实现不带参数的简单 SQL 语句。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的MySQL JDBC驱动,将其注册到DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库URL的连接。
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
        // ③创建一个Statement对象,用于向数据库发送SQL语句。
        Statement statement = connection.createStatement();

    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出ClassNotFoundException异常。
        e.printStackTrace();
    } catch (SQLException throwables) {
        // ②如果数据库访问错误发生或url为空时,会抛出SQLException异常。
        throwables.printStackTrace();
    }
}

大家看上述代码的③处,创建了 Statement 对象后赋值给 statement 变量。

第四步:执行 SQL 语句并处理返回结果

Statement 用于执行不带参数的简单的静态 SQL 语句,并返回其产生的结果。我们可以看一下 Statement 这个类提供的方法:

在这里插入图片描述
方法有很多,对于入门的我们来说掌握前两个即可。

第一个 executeQuery(),执行 select 查询语句,返回结果集 ResultSetexecute 是执行的意思,query 就是查询的意思。这个两个单词在编程中经常见。

/**
 * 执行给定的SQL语句,该语句返回单个ResultSet对象。
 * 参数:sql—发送到数据库的sql语句,通常是静态sql SELECT语句
 * 返回:一个ResultSet对象,其中包含给定查询产生的数据;没有空
 * 
 */
ResultSet executeQuery(String sql) throws SQLException;

第二个 executeUpdate(),执行更新操作,比如 insertupdatedelete 语句,返回执行的行数。update 就是更新的意思。这个单词在编程中也经常见。

/**
 * 执行给定的SQL语句,该语句可以是INSERT、UPDATE或DELETE语句,也可以是不返回任何结果的SQL语句,例如SQL DDL语句。
 * 参数:sql—sql数据操作语言(DML)语句,如INSERT, UPDATE或DELETE;或者是不返回任何结果的SQL语句,比如DDL语句。
 * 返回:(1)SQL数据操作语言(DML)语句的行数,或(2)不返回任何结果的SQL语句的0
 */
int executeUpdate(String sql) throws SQLException;

接下来我们使用 executeQuery() 方法,查询 teacher 表中的数据,上代码。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的MySQL JDBC驱动,将其注册到DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库URL的连接。
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
        // ③创建一个Statement对象,用于向数据库发送SQL语句。
        Statement statement = connection.createStatement();
        // ④执行SQL语句并返回结果
        ResultSet resultSet = statement.executeQuery("select * from teacher");

    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出ClassNotFoundException异常。
        e.printStackTrace();
    } catch (SQLException throwables) {
        // ②如果数据库访问错误发生或url为空时,会抛出SQLException异常。
        throwables.printStackTrace();
    }
}

上述代码④处,调用 Statement 对象中的 executeQuery() 执行 SQL 语句select * from teacher,查询 teacher 表中全部数据,注意没有结束 ; 号。将查询结果封装在 ResultSet 结果集,我们需要接收一下。

第五步:处理 SQL 执行的结果

处理结果集,也就是我们需要从 ResultSet 中将查询的数据取出来。通过游标访问对象中的数据。它就是 ResultSet 类中的 next()。请注意,此游标不是数据库游标。此光标是指向对象中一行数据的指针。最初,光标位于第一行之前。大家仔细阅读下面⑤处代码。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的MySQL JDBC驱动,将其注册到DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库URL的连接。
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
        // ③创建一个Statement对象,用于向数据库发送SQL语句。
        Statement statement = connection.createStatement();
        // ④执行SQL语句并返回结果
        ResultSet resultSet = statement.executeQuery("select * from teacher");
        // ⑤处理SQL语句执行的结果
        while(resultSet.next()){
            // 从结果集将当前行数据取出
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String sex = resultSet.getString("sex");
            int age = resultSet.getInt(4);
            // 打印输出当前行数据
            System.out.println("id:" + id + ",name:" + name + ",sex:" + sex + ",age:" + age);
        }

    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出ClassNotFoundException异常。
        e.printStackTrace();
    } catch (SQLException throwables) {
        // ②如果数据库访问错误发生或url为空时,会抛出SQLException异常。
        throwables.printStackTrace();
    }
}

由于 select 语句查询的结果可能为多行,故使用 while 循环,条件就是 next() 方法,该方法返回 boolean 值。上面说过 ResultSet 游标最初定位在第一行之前,那么 while 循环中该方法的第一次调用 next 使第一行成为当前行,第二次调用将第二行作为当前行,依此类推。当对 next 方法的调用返回 false 时,游标定位在最后一行之后。

那么在循环体内,我们就可以将当前行数据取出,如何取出数据呢?ResultSet 类中提供了一系列方法。

在这里插入图片描述

取数据,我们使用 get 开头的方法,比如 getInt() 方法是取出某列的 int 类型数据,getString() 方法就是取出字符串类型数据。

我们可以看到 getInt() 方法有两个,这两个方法就是重载,方法重载(Overloading)是指在同一个类中,允许存在多个同名方法,但这些方法的参数列表必须不同。

获取其他类型数据也都有两个方法,它们的参数类型不同。

/**
 * 以Java编程语言的int形式检索此ResultSet对象当前行的指定列的值。
 * columnLabel—用SQL AS子句指定的列的标签。如果没有指定SQL AS子句,则标签是列的名称
 */
int getInt(String columnLabel) throws SQLException;
/**
 * 以Java编程语言的int形式检索此ResultSet对象当前行的指定列的值。
 * columnIndex -第一列是1,第二列是2,…
 */
int getInt(int columnIndex) throws SQLException;

简单来说第一个方法是根据列名获取数据,第二个方法是根据列号获取数据。哪种方式更好呢?当然是第一种根据列名,如果根据第几列获取,很容易搞混,而且代码不易维护。

第六步:关闭资源

当我们使用完对象后,调用其方法以立即释放它正在使用的资源。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    try {
        // ①动态加载指定路径下的MySQL JDBC驱动,将其注册到DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库URL的连接。
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
        // ③创建一个Statement对象,用于向数据库发送SQL语句。
        Statement statement = connection.createStatement();
        // ④执行SQL语句并返回结果
        ResultSet resultSet = statement.executeQuery("select * from teacher");
        // ⑤处理SQL语句执行的结果
        while(resultSet.next()){
            // 从结果集将当前行数据取出
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String sex = resultSet.getString("sex");
            int age = resultSet.getInt(4);
            // 打印输出当前行数据
            System.out.println("id:" + id + ",name:" + name + ",sex:" + sex + ",age:" + age);
        }

        // ⑥关闭资源,关闭顺序:从里到外的原则,保证该资源确定不再使用后关闭
        resultSet.close();
        statement.close();
        connection.close();

    } catch (ClassNotFoundException e) {
        // ①加载的类找不到时,会抛出ClassNotFoundException异常。
        e.printStackTrace();
    } catch (SQLException throwables) {
        // ②如果数据库访问错误发生或url为空时,会抛出SQLException异常。
        throwables.printStackTrace();
    }
}

上述代码⑥处,调用了三个对象的 close() 方法来关闭我们使用的资源。这些资源在使用完毕之后是一定要进行关闭的,不然这些资源可能一致被占用。

到这里一个 JDBC 编程基本步骤就完成了,最后就是验证成果的时候了。我们运行程序,查看控制台是否会打印出 teacher 表中的数据。

在这里插入图片描述

四、代码优化

对 JDBC 编程基本步骤中的代码进行优化,有兴趣的可以看一下。

1.简单优化

主要优化的地方是将关闭资源操作放在 finally 块中,即程序无论正确执行还是抛出异常都要关闭资源。

/**
 * 敲入main,根据提示自动生成主函数main()方法
 * @param args
 */
public static void main(String[] args) {
    // 将Connection、Statement、ResultSet对象变量提取至try...catch外
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;

    try {
        // ①动态加载指定路径下的MySQL JDBC驱动,将其注册到DriverManager中。
        Class.forName("com.mysql.cj.jdbc.Driver");
        // ②建立到给定数据库URL的连接。
        connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test_jdbc?serverTimezone=Asia/Shanghai", "root", "root");
        // ③创建一个Statement对象,用于向数据库发送SQL语句。
        statement = connection.createStatement();
        // ④执行SQL语句并返回结果
        resultSet = statement.executeQuery("select * from teacher");
        // ⑤处理SQL语句执行的结果
        while(resultSet.next()){
            // 从结果集将当前行数据取出
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String sex = resultSet.getString("sex");
            int age = resultSet.getInt(4);
            // 打印输出当前行数据
            System.out.println("id:" + id + ",name:" + name + ",sex:" + sex + ",age:" + age);
        }

    } catch (ClassNotFoundException | SQLException e) {
        /* 异常合并到一起
         * ①加载的类找不到时,会抛出ClassNotFoundException异常。
         * ②如果数据库访问错误发生或url为空时,会抛出SQLException异常。
         */
        e.printStackTrace();
    } finally {
        try {
            // ⑥关闭资源,关闭顺序:从里到外的原则,保证该资源确定不再使用
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

2.with-resources探讨

其实除了上述的简单优化,还可以使用 with-resources 来自动关闭资源。with-resources 是 Java 7 引入的一个新特性,用于自动管理资源的关闭。它允许在 try-with-resources 语句中声明需要关闭的资源,当 try 代码块执行完毕后,资源会自动被关闭,无需显式调用 close() 方法。使用 with-resources 可以简化代码,避免资源泄漏和手动关闭资源的繁琐操作。它适用于实现了 java.lang.AutoCloseable 接口的资源对象,包括文件流、数据库连接、网络连接等。

ConnectionStatementResultSet都实现了 java.lang.AutoCloseable 接口,也就说这三个资源可以使用 with-resources 来自动关闭。需要注意的是,使用 with-resources 语句时,资源对象的初始化必须在 try 代码块之前完成。以下是示例代码:

try (FileInputStream fis = new FileInputStream("file.txt");
     BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

从代码中可以看出要关闭的资源在 try() 内初始化的,那对于咱们 JDBC 来说 ConnectionStatementResultSet 都在 try() 内初始化,感觉乱,并不舒服。所以我就想了想,没有去尝试。有兴趣的小伙伴可以尝试一下,对于 JDBC 关闭资源,with-resources 这个特性是不是有优势。


总结

Java EE 中关于 JDBC API,是使用 Java SE 中的 JDBC。

Java 提供一个标准的 JDBC 接口,也就是定义这一规范。然后由各数据库厂商负责实现。所以我们想用 Java 连接哪个数据库,就需要有哪个数据库的 JDBC 驱动程序。

JDBC 负责三件事:

  1. 连接到数据源,如数据库
  2. 向数据库发送查询和更新语句
  3. 检索并处理从数据库接收到的结果

JDBC 具体编程步骤:

  1. 引入驱动并加载
  2. 建立数据库连接
  3. 创建语句对象
  4. 执行SQL语句并返回结果
  5. 处理结果
  6. 关闭资源

只是看是学不会的,要赋予实际的行动——敲代码!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895238.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring框架之揭秘Bean的生命周期与单例详解【面试题超详细回答】

目录 一、前言 1.1.介绍Spring框架和Bean的概念 二、Bean的实例化阶段 2.1.Bean的实例化过程 2.2.介绍默认构造函数和工厂方法的使用 三、Bean的初始化阶段 3.1.InitializingBean接口和PostConstruct注解的使用 3.2.Bean的初始化方法配置和执行顺序 四、Bean的销毁阶段…

数据库变革:HashData云数仓实现事务级实时性

8月16-18日,第十四届中国数据库技术大会(DTCC 2023)在北京召开。酷克数据资深解决方案架构师陈义贤在“数据库内核•技术创新”专场发表题为“分布式数仓的TP能力探索—HashData UnionStore”的演讲,介绍HashData以Log is databas…

QT的mysql(数据库)最佳实践和常见问题解答

涉及到数据库,首先安利一个软件Navicat Premium,用来查询数据库很方便 QMysql驱动是Qt SQL模块使用的插件,用于与MySQL数据库进行通信。要编译QMysql驱动,您需要满足以下条件: 您需要安装MySQL的客户端库和开发头文件…

三生ONE物,无限可能|博睿数据上市三周年!

2020年8月17日,北京博睿宏远数据科技股份有限公司作为国内A股市场上的“APM应用性能监控第一股”公司,在科创板荣登上市!(股票号688229) 2023年8月17日,三载日夜更替,博睿一路砥砺前行&#xf…

Eclipse集成MapStruct

Eclipse集成MapStruct 在Eclipse中添加MapStruct依赖配置Eclipse支持MapStruct①安装 m2e-aptEclipse Marketplace的方式安装Install new software的方式安装(JDK8用到) ②添加到pom.xml 今天拿到同事其他项目的源码,导入并运行的时候抛出了异…

Channel是什么?FileChannel类的常用方法

Channel 是一个接口对象,它类似于传统的流对象,但与传统的流对象又有些不同,具体表现如下: • Channel可以异步地执行I/O读写操作。 • Channel的读写操作是双向的,既可以从 Channel中读取数据,又可以写数据到Channel,而流的读写操作通常都是单向的。 • Channel…

Can‘t find end of central directory : is this a zip file ? at XMLHttpRequest

导出woed出现这个报错,原因其实很简单,路径写错了, 这个word首先必须是docx格式,然后必须放在public文件包下 如果放在public文件包下还没有用,则放在public包下 参考帖子: https://www.cnblogs.com/hejun26/p/13647927.html

VR漫游:720度实景参观,打造魅力生态小区

随着城市的不断发展,小区的建设越发具有生态化、绿色化的特点,人们也会偏向选择更加适合居住的小区。为了让更多的用户体验小区的舒适性,不少地产开发商准备引入VR漫游技术。 VR漫游不仅能够真实地展示现场环境,还可以改变传统网络…

shell编程 基础

将content.txt文件中的内容输出到控制台上 将content.txt中有tom的行输出到控制台 将$2文件中含有gree的行输出到控制台 case语法 简易计算器 查找有root的行 查找以root开头的行 查询时忽略大小写 grep -E 则适用于复杂的正则表达式,可以使用多项选择、重复和子表达…

开发者不可错过的提效工具——低代码开发

开发者不可错过的提效工具 基础低码功能及搭建 01、代码生成器 02、工作流程 03、门户设计 04、大屏设计 05、报表设计 06、第三方登录 07、多租户实现 08、分布式调度 为什么低码平台能够成为开发者的宠儿? 1.低码平台能够大幅提高开发效率 2.低码平台具备高度的可…

QString常用函数介绍

此篇博客核心介绍QT中的QString类型的常用函数,介绍到的函数均从帮助手册或其他博客中看到 QString 字符串类 Header: #include qmake: QT core 一、QString字符串转换 1、QString类字符串转换为整数 int toInt(bool *ok Q_NULLPTR, int base 10) cons…

NOTA标记多肽氨基酸试剂,NOTA-E(cRGDfK)2的化学特性

今日文章关键词:DOTA 偶联肽,NOTA-E(cRGDfK)2,NOTA标记多肽氨基酸试剂 产品描述:DOTATATE acetate 是一种 DOTA 偶联肽,可以被放射性核素标记以用于正电子发射断层扫描 (PET) 成像和肽受体放射性核素治疗 (PRRT)。 英…

LLM的生成配置中参数含义

LLM的生成配置中参数含义 我们在Huggingface中第一次使用大模型的时候,常常会看到一些需要调整的参数,这个参数也是需要了解的。 文中都是来自对于 LLM 一些学习资料的整理 在上图中有 4 个配置的参数分别是 Max new tokens、top-k、top-p以及 Temperature。 token相信大家都…

idea 转换为 Maven Project 的方法

选项: Add as Maven Project

Android 12 源码分析 —— 应用层 一(SystemUI准备篇)

Android 12 源码分析 —— 应用层一(SystemUI准备篇) 在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。 先从android的应用层进行探析,然后慢慢深入android的fr…

运维节点CPU飙升问题分析

工作内容,不对外开放 前言 首先问题是这样的,周五正在写文档,突然收到了线上报警,发现cpu占用达到了90多,上平台监控系统查看容器,在jvm监控中发现有一个pod在两个小时内产生了61次youngGc一次fullGc,这个问题特别严重且少见,由于我之前也没有排查过此类问题,所以也是…

8个免费的在线思维导图制作工具推荐,节省时间提高效率!

思维导图,也称为心智图或思维图,最初由英国的心理学家Tony Buzan提出。它是一种图形化的思维工具,旨在帮助我们组织信息、理解知识和激发创新思维。思维导图最大特点是其中心放射式的结构。一张思维导图通常由一个中心主题发散出各个子主题&a…

真知灼见|鲸图知识图谱平台,助力金融业务深度洞察(下)

导语 大数据时代的背景下,数据早就成为数字经济重要的生产资料。对数据的挖掘能力成为企业数字化转型的驱动力。就金融行业来说,如果经营和管理方式跟不上大数据时代的发展脚步就会使得数据价值无法得到充分发挥。知识图谱作为一个结合了知识存储、知识…

HVV(护网)行动详解

前言 最近的全国护网可谓是正在火热的进行中,有很多网安小白以及准大一网安的同学在后台问我,到底什么是护网啊?怎么参加呢?有没有相关的学习资料呢?在下不才,连夜整理出来了这篇护网详解文章,希…

msvcp110.dll是什么意思,msvcp110.dll丢失的解决方法

装好软件或游戏之后,一打开就跳出各种报错信息的情况小伙伴一定见过,其中缺少各种msvcp110.dll文件最常见。小伙伴们一定奇怪,用得好好的电脑,怎么会缺文件呢?为啥其他游戏/应用就没事呢?其实这些“丢失”的…