Java 中文官方教程 2022 版(三十六)(2)

简介: Java 中文官方教程 2022 版(三十六)

Java 中文官方教程 2022 版(三十六)(1)https://developer.aliyun.com/article/1488068

存储和更新数组对象

使用方法PreparedStatement.setArrayPreparedStatement.setObjectArray值作为输入参数传递给PreparedStatement对象。

以下示例将在先前创建的Array对象anArray设置为pstmt的第二个参数:

PreparedStatement pstmt = con.prepareStatement(
    "insert into REGIONS (region_name, zips) " + "VALUES (?, ?)");
pstmt.setString(1, "NorthEast");
pstmt.setArray(2, anArray);
pstmt.executeUpdate();

同样,使用方法PreparedStatement.updateArrayPreparedStatement.updateObject来使用Array值更新表中的列。

释放数组资源

Array对象在创建它们的事务持续时间内保持有效。这可能导致应用程序在长时间运行的事务中耗尽资源。应用程序可以通过调用它们的free方法来释放Array资源。

在以下摘录中,调用方法Array.free来释放先前创建的Array对象所持有的资源。

Array aArray = con.createArrayOf("VARCHAR", northEastRegionnewYork);
// ...
aArray.free();

使用 DISTINCT 数据类型

原文:docs.oracle.com/javase/tutorial/jdbc/basics/distinct.html

注意:MySQL 和 Java DB 目前不支持DISTINCT SQL 数据类型。因此,在本节描述的功能没有 JDBC 教程示例可用来演示。

DISTINCT 数据类型与其他高级 SQL 数据类型的行为不同。作为一个基于已有内置类型之一的用户定义类型,它没有接口作为其在 Java 编程语言中的映射。相反,DISTINCT 数据类型的标准映射是其底层 SQL 数据类型映射到的 Java 类型。

为了说明,创建一个DISTINCT数据类型,然后看看如何检索、设置或更新它。假设你总是使用两个字母的缩写表示一个州,并且想要创建一个用于这些缩写的DISTINCT数据类型。你可以使用以下 SQL 语句定义你的新DISTINCT数据类型:

CREATE TYPE STATE AS CHAR(2);

一些数据库使用另一种语法来创建DISTINCT数据类型,如下面的代码行所示:

CREATE DISTINCT TYPE STATE AS CHAR(2);

如果一个语法不起作用,你可以尝试另一个。或者,你可以查看你的驱动程序文档,以查看它期望的确切语法。

这些语句创建了一个新的数据类型STATE,它可以作为列值或作为 SQL 结构化类型的属性值使用。因为STATE类型的值实际上是两个CHAR类型的值,所以你使用与检索CHAR值相同的方法来检索它,即getString。例如,假设ResultSet *rs*的第四列存储了STATE类型的值,下面的代码行检索了它的值:

String state = rs.getString(4);

同样,你会使用setString方法将STATE值存储在数据库中,使用updateString方法修改其值。

使用结构化对象

原文:docs.oracle.com/javase/tutorial/jdbc/basics/sqlstructured.html

注意:MySQL 和 Java DB 目前不支持用户定义类型。因此,没有 JDBC 教程示例可用来演示本节描述的功能。

下列主题包括:

  • 结构化类型概述
  • 在结构化类型中使用 DISTINCT 类型
  • 使用结构化类型的引用
  • 创建 SQL REF 对象的示例代码
  • 将用户定义类型用作列值
  • 将用户定义类型插入表中

结构化类型概述

SQL 结构化类型和DISTINCT类型是用户可以在 SQL 中定义的两种数据类型。它们通常被称为 UDT(用户定义类型),您可以使用 SQL 的CREATE TYPE语句来创建它们。

回到 The Coffee Break 的例子,假设所有者的成功超出了所有预期,并且一直在扩张新分店。所有者决定向数据库添加一个STORES表,其中包含有关每个机构的信息。STORES将有四列:

  • STORE_NO代表每个店铺的识别号
  • LOCATION代表其地址
  • COF_TYPES代表其销售的咖啡
  • MGR代表店长的姓名

所有者将LOCATION列设为 SQL 结构化类型,COF_TYPES列设为 SQL ARRAYMGR列设为REF(MANAGER),其中MANAGER是 SQL 结构化类型。

所有者首先必须为地址和经理定义新的结构化类型。SQL 结构化类型类似于 Java 编程语言中的结构化类型,它具有称为属性的成员,可以是任何数据类型。所有者编写以下 SQL 语句来创建新数据类型ADDRESS

CREATE TYPE ADDRESS
(
    NUM INTEGER,
    STREET VARCHAR(40),
    CITY VARCHAR(40),
    STATE CHAR(2),
    ZIP CHAR(5)
);

在此语句中,新类型ADDRESS有五个属性,类似于 Java 类中的字段。属性NUM是一个INTEGER,属性STREET是一个VARCHAR(40),属性CITY是一个VARCHAR(40),属性STATE是一个CHAR(2),属性ZIP是一个CHAR(5)

下面的摘录中,con是一个有效的Connection对象,将ADDRESS的定义发送到数据库:

String createAddress =
    "CREATE TYPE ADDRESS " +
    "(NUM INTEGER, STREET VARCHAR(40), " +
    "CITY VARCHAR(40), STATE CHAR(2), ZIP CHAR(5))";
Statement stmt = con.createStatement();
stmt.executeUpdate(createAddress);

现在ADDRESS结构化类型已在数据库中注册为数据类型,所有者可以将其用作表列或结构化类型属性的数据类型。

在结构化类型中使用 DISTINCT 类型

The Coffee Break 的所有者计划在新的结构化类型MANAGER中包含的属性之一是经理的电话号码。因为所有者总是将电话号码列为一个 10 位数(以确保包括区号),并且永远不会将其作为数字进行操作,所以所有者决定定义一个名为PHONE_NO的新类型,该类型由 10 个字符组成。这种数据类型的 SQL 定义,可以被视为只有一个属性的结构化类型,如下所示:

CREATE TYPE PHONE_NO AS CHAR(10);

或者,如前面提到的,对于某些驱动程序,定义可能如下所示:

CREATE DISTINCT TYPE PHONE_NO AS CHAR(10);

DISTINCT类型始终基于另一个数据类型,该数据类型必须是预定义类型。换句话说,DISTINCT类型不能基于用户定义类型(UDT)。要检索或设置DISTINCT类型的值,请使用基础类型(其基础类型)的适当方法。例如,要检索基于CHAR类型的PHONE_NO实例,您将使用getString方法,因为这是检索CHAR的方法。

假设ResultSet对象*rs*的当前行的第四列中有一个类型为PHONE_NO的值,以下代码行检索它:

String phoneNumber = rs.getString(4);

类似地,以下代码行设置了一个输入参数,该参数具有类型PHONE_NO,用于发送到数据库的预备语句:

pstmt.setString(1, phoneNumber);

在前面的代码片段中添加,PHONE_NO的定义将通过以下代码行发送到数据库:

stmt.executeUpdate(
    "CREATE TYPE PHONE_NO AS CHAR(10)");

在向数据库注册类型PHONE_NO之后,所有者可以将其用作表中的列类型或作为结构化类型中属性的数据类型。以下 SQL 语句中MANAGER的定义使用PHONE_NO作为属性PHONE的数据类型:

CREATE TYPE MANAGER
(
    MGR_ID INTEGER,
    LAST_NAME VARCHAR(40),
    FIRST_NAME VARCHAR(40),
    PHONE PHONE_NO
);

重用之前定义的*stmt*,以下代码片段将结构化类型MANAGER的定义发送到数据库:

String createManager =
    "CREATE TYPE MANAGER " +
    "(MGR_ID INTEGER, LAST_NAME " +
    "VARCHAR(40), " +
    "FIRST_NAME VARCHAR(40), " +
    "PHONE PHONE_NO)";
  stmt.executeUpdate(createManager);

使用结构化类型的引用

The Coffee Break 的所有者创建了三种新的数据类型,用作数据库中的列类型或属性类型:结构化类型LOCATIONMANAGER,以及DISTINCT类型PHONE_NO。企业家将PHONE_NO用作新类型MANAGER中属性PHONE的类型,并将ADDRESS用作表STORES中列LOCATION的数据类型。MANAGER类型可以用作列MGR的类型,但企业家更喜欢使用类型REF(MANAGER),因为企业家经常让一个人管理两到三家店铺。将REF(MANAGER)用作列类型可以避免在一个人管理多家店铺时重复所有MANAGER的数据。

已经创建了结构化类型 MANAGER,所有者现在可以创建一个包含可以被引用的 MANAGER 实例的表。对 MANAGER 实例的引用将具有类型 REF(MANAGER)。SQL REF 只不过是指向结构化类型的逻辑指针,因此 REF(MANAGER) 实例充当对 MANAGER 实例的逻辑指针。

因为 SQL REF 值需要永久与其引用的结构化类型实例关联在一起,所以它存储在一个特殊的表中,与其关联的实例一起。程序员不直接创建 REF 类型,而是创建将存储特定结构化类型实例的表,这些实例可以被引用。每个要被引用的结构化类型都将有自己的表。当你将结构化类型的实例插入表中时,数据库会自动创建一个 REF 实例。例如,为了包含可以被引用的 MANAGER 实例,所有者使用 SQL 创建了以下特殊表:

CREATE TABLE MANAGERS OF MANAGER
  (OID REF(MANAGER)
  VALUES ARE SYSTEM GENERATED);

这个语句创建了一个带有特殊列 OID 的表,该列存储 REF(MANAGER) 类型的值。每次将 MANAGER 实例插入表中时,数据库都会生成一个 REF(MANAGER) 实例并将其存储在列 OID 中。隐式地,另外一列存储已插入表中的 MANAGER 的每个属性。例如,以下代码片段展示了企业家如何创建了三个 MANAGER 结构化类型的实例来代表三个经理:

INSERT INTO MANAGERS (
    MGR_ID, LAST_NAME,
    FIRST_NAME, PHONE) VALUES
  (
    000001,
    'MONTOYA',
    'ALFREDO',
    '8317225600'
  );
  INSERT INTO MANAGERS (
    MGR_ID, LAST_NAME,
    FIRST_NAME, PHONE) VALUES
  (
    000002,
    'HASKINS',
    'MARGARET',
    '4084355600'
  );
  INSERT INTO MANAGERS (
    MGR_ID, LAST_NAME,
    FIRST_NAME, PHONE) VALUES
  (
    000003,
    'CHEN',
    'HELEN',
    '4153785600'
   );

MANAGERS 现在将有三行,每个已插入的经理一行。列 OID 将包含三个 REF(MANAGER) 类型的唯一对象标识符,每个 MANAGER 实例一个。这些对象标识符是由数据库自动生成的,并将永久存储在表 MANAGERS 中。隐式地,另外一列存储 MANAGER 的每个属性。例如,在表 MANAGERS 中,一行包含一个引用 Alfredo Montoya 的 REF(MANAGER),另一行包含一个引用 Margaret Haskins 的 REF(MANAGER),第三行包含一个引用 Helen Chen 的 REF(MANAGER)

要访问 REF(MANAGER) 实例,您可以从其表中选择。例如,所有者使用以下代码片段检索了对 ID 号为 000001 的 Alfredo Montoya 的引用:

String selectMgr =
    "SELECT OID FROM MANAGERS " +
    "WHERE MGR_ID = 000001";
  ResultSet rs = stmt.executeQuery(selectMgr);
  rs.next();
  Ref manager = rs.getRef("OID");

现在变量 *manager* 可以被用作引用 Alfredo Montoya 的列值。

创建 SQL REF 对象的示例代码

以下代码示例创建了表MANAGERS,这是结构化类型MANAGER的实例表,可以引用,并将三个MANAGER实例插入表中。此表中的列OID将存储REF(MANAGER)的实例。执行此代码后,MANAGERS表将为插入的三个MANAGER对象的每个对象插入一行,并且OID列中的值将是标识存储在该行中的MANAGER实例的REF(MANAGER)类型。

package com.oracle.tutorial.jdbc;
import java.sql.*;
public class CreateRef {
    public static void main(String args[]) {
        JDBCTutorialUtilities myJDBCTutorialUtilities;
        Connection myConnection = null;
        if (args[0] == null) {
            System.err.println("Properties file not specified " +
                               "at command line");
            return;
        } else {
            try {
                myJDBCTutorialUtilities = new JDBCTutorialUtilities(args[0]);
            } catch (Exception e) {
                System.err.println("Problem reading properties " +
                                   "file " + args[0]);
                e.printStackTrace();
                return;
            }
        }
        Connection con = null;
        Statement stmt = null;
        try {
            String createManagers =
                "CREATE TABLE " +
                "MANAGERS OF MANAGER " +
                "(OID REF(MANAGER) " +
                "VALUES ARE SYSTEM " +
                "GENERATED)";
            String insertManager1 =
                "INSERT INTO MANAGERS " +
                "(MGR_ID, LAST_NAME, " +
                "FIRST_NAME, PHONE) " +
                "VALUES " +
                "(000001, 'MONTOYA', " +
                "'ALFREDO', " +
                "'8317225600')";
            String insertManager2 =
                "INSERT INTO MANAGERS " +
                "(MGR_ID, LAST_NAME, " +
                "FIRST_NAME, PHONE) " +
                "VALUES " +
                "(000002, 'HASKINS', " +
                "'MARGARET', " +
                "'4084355600')";
            String insertManager3 =
                "INSERT INTO MANAGERS " +
                "(MGR_ID, LAST_NAME, " +
                "FIRST_NAME, PHONE) " +
                "VALUES " +
                "(000003, 'CHEN', 'HELEN', " +
                "'4153785600')";
            con = myJDBCTutorialUtilities.getConnection();
            con.setAutoCommit(false);
            stmt = con.createStatement();
            stmt.executeUpdate(createManagers);
            stmt.addBatch(insertManager1);
            stmt.addBatch(insertManager2);
            stmt.addBatch(insertManager3);
            int [] updateCounts = stmt.executeBatch();
            con.commit();
            System.out.println("Update count for:  ");
            for (int i = 0; i < updateCounts.length; i++) {
                System.out.print("    command " + (i + 1) + " = ");
                System.out.println(updateCounts[i]);
            }
        } catch(BatchUpdateException b) {
            System.err.println("-----BatchUpdateException-----");
            System.err.println("Message:  " + b.getMessage());
            System.err.println("SQLState:  " + b.getSQLState());
            System.err.println("Vendor:  " + b.getErrorCode());
            System.err.print("Update counts for " + "successful commands:  ");
            int [] rowsUpdated = b.getUpdateCounts();
            for (int i = 0; i < rowsUpdated.length; i++) {
                System.err.print(rowsUpdated[i] + "   ");
            }
            System.err.println("");
        } catch(SQLException ex) {
            System.err.println("------SQLException------");
            System.err.println("Error message:  " + ex.getMessage());
            System.err.println("SQLState:  " + ex.getSQLState());
            System.err.println("Vendor:  " + ex.getErrorCode());
        } finally {
            if (stmt != null) { stmt.close(); }
              JDBCTutorialUtilities.closeConnection(con);
        }
    }
}

使用用户定义类型作为列值

我们的企业家现在拥有创建表STORES所需的 UDT。结构化类型ADDRESS是列LOCATION的类型,类型REF(MANAGER)是列MGR的类型。

UDT COF_TYPES基于 SQL 数据类型ARRAY,是列COF_TYPES的类型。以下代码行创建了类型COF_ARRAY作为具有 10 个元素的ARRAY值。COF_ARRAY的基本类型是VARCHAR(40)

CREATE TYPE COF_ARRAY AS ARRAY(10) OF VARCHAR(40);

定义了新数据类型后,以下 SQL 语句创建了表STORES

CREATE TABLE STORES
  (
    STORE_NO INTEGER,
    LOCATION ADDRESS,
    COF_TYPES COF_ARRAY,
    MGR REF(MANAGER)
  );

将用户定义类型插入表中

以下代码片段向STORES表中插入一行,按顺序提供了列STORE_NOLOCATIONCOF_TYPESMGR的值:

INSERT INTO STORES VALUES
  (
    100001,
    ADDRESS(888, 'Main_Street',
      'Rancho_Alegre',
      'CA', '94049'),
    COF_ARRAY('Colombian', 'French_Roast',
      'Espresso', 'Colombian_Decaf',
      'French_Roast_Decaf'),
    SELECT OID FROM MANAGERS
      WHERE MGR_ID = 000001
  );

以下逐个列出每列及其插入的值。

STORE_NO: 100001

此列类型为INTEGER,数字100001INTEGER类型,类似于之前在COFFEESSUPPLIERS表中插入的条目。

LOCATION: ADDRESS(888, 'Main_Street',
    'Rancho_Alegre', 'CA', '94049')

此列的类型为结构化类型ADDRESS,此值是ADDRESS实例的构造函数。当我们将ADDRESS的定义发送到数据库时,其中一件事是为新类型创建构造函数。括号中的逗号分隔值是ADDRESS类型属性的初始化值,它们必须按照ADDRESS类型定义中属性列出的顺序出现。888是属性NUM的值,是INTEGER值。"Main_Street"STREET的值,"Rancho_Alegre"CITY的值,这两个属性都是VARCHAR(40)类型。属性STATE的值为"CA",是CHAR(2)类型,属性ZIP的值为"94049",是CHAR(5)类型。

COF_TYPES: COF_ARRAY(
    'Colombian',
    'French_Roast',
    'Espresso',
    'Colombian_Decaf',
    'French_Roast_Decaf'),

COF_TYPES的类型为COF_ARRAY,基本类型为VARCHAR(40),括号中的逗号分隔值是数组元素为String对象。所有者定义了类型COF_ARRAY最多有 10 个元素。此数组有 5 个元素,因为企业家仅提供了 5 个String对象。

MGR: SELECT OID FROM MANAGERS
    WHERE MGR_ID = 000001

MGR的类型是REF(MANAGER),这意味着该列中的值必须是指向结构化类型MANAGER的引用。所有MANAGER的实例都存储在表MANAGERS中。所有REF(MANAGER)的实例也存储在该表中,存储在列OID中。此表行中描述的商店的经理是 Alfredo Montoya,他的信息存储在具有属性MGR_ID100001MANAGER实例中。要获取与 Alfredo Montoya 的MANAGER对象关联的REF(MANAGER)实例,请选择表MANAGERSMGR_ID100001的行中的列OID。将存储在STORES表的MGR列中的值(REF(MANAGER)值)是 DBMS 生成的用于唯一标识此MANAGER结构化类型实例的值。

将上述 SQL 语句发送到数据库,使用以下代码片段:

String insertMgr =
    "INSERT INTO STORES VALUES " +
    "(100001, " +
    "ADDRESS(888, 'Main_Street', " +
      "'Rancho_Alegre', 'CA', " +
      "'94049'), " +
    "COF_ARRAY('Colombian', " +
      "'French_Roast', 'Espresso', " +
      "'Colombian_Decaf', " +
      "'French_Roast_Decaf'}, " +
    "SELECT OID FROM MANAGERS " +
    "WHERE MGR_ID = 000001)";
  stmt.executeUpdate(insertMgr);

然而,因为你将发送多个INSERT INTO语句,将它们一起作为批量更新发送会更有效,就像以下代码示例中所示:

package com.oracle.tutorial.jdbc;
import java.sql.*;
public class InsertStores {
    public static void main(String args[]) {
        JDBCTutorialUtilities myJDBCTutorialUtilities;
        Connection myConnection = null;
        if (args[0] == null) {
            System.err.println(
                "Properties file " +
                "not specified " +
                "at command line");
            return;
        } else {
            try {
                myJDBCTutorialUtilities = new
                    JDBCTutorialUtilities(args[0]);
            } catch (Exception e) {
                System.err.println(
                    "Problem reading " +
                    "properties file " +
                    args[0]);
                e.printStackTrace();
                return;
            }
        }
        Connection con = null;
        Statement stmt = null;
        try {
            con = myJDBCTutorialUtilities.getConnection();
            con.setAutoCommit(false);
            stmt = con.createStatement();
            String insertStore1 =
                "INSERT INTO STORES VALUES (" +
                "100001, " +
                "ADDRESS(888, 'Main_Street', " +
                    "'Rancho_Alegre', 'CA', " +
                    "'94049'), " +
                "COF_ARRAY('Colombian', " +
                    "'French_Roast', " +
                    "'Espresso', " +
                    "'Colombian_Decaf', " +
                    "'French_Roast_Decaf'), " +
                "(SELECT OID FROM MANAGERS " +
                "WHERE MGR_ID = 000001))";
            stmt.addBatch(insertStore1);
            String insertStore2 =
                "INSERT INTO STORES VALUES (" +
                "100002, " +
                "ADDRESS(1560, 'Alder', " +
                    "'Ochos_Pinos', " +
                    "'CA', '94049'), " +
                "COF_ARRAY('Colombian', " +
                    "'French_Roast', " +
                    "'Espresso', " +
                    "'Colombian_Decaf', " +
                    "'French_Roast_Decaf', " +
                    "'Kona', 'Kona_Decaf'), " +
                "(SELECT OID FROM MANAGERS " +
                "WHERE MGR_ID = 000001))";
            stmt.addBatch(insertStore2);
            String insertStore3 =
                "INSERT INTO STORES VALUES (" +
                "100003, " +
                "ADDRESS(4344, " +
                    "'First_Street', " +
                    "'Verona', " +
                    "'CA', '94545'), " +
                "COF_ARRAY('Colombian', " +
                    "'French_Roast', " +
                    "'Espresso', " +
                    "'Colombian_Decaf', " +
                    "'French_Roast_Decaf', " +
                    "'Kona', 'Kona_Decaf'), " +
                "(SELECT OID FROM MANAGERS " +
                "WHERE MGR_ID = 000002))";
            stmt.addBatch(insertStore3);
            String insertStore4 =
                "INSERT INTO STORES VALUES (" +
                "100004, " +
                "ADDRESS(321, 'Sandy_Way', " +
                    "'La_Playa', " +
                    "'CA', '94544'), " +
                "COF_ARRAY('Colombian', " +
                    "'French_Roast', " +
                    "'Espresso', " +
                    "'Colombian_Decaf', " +
                    "'French_Roast_Decaf', " +
                    "'Kona', 'Kona_Decaf'), " +
                "(SELECT OID FROM MANAGERS " +
                "WHERE MGR_ID = 000002))";
            stmt.addBatch(insertStore4);
            String insertStore5 =
                "INSERT INTO STORES VALUES (" +
                "100005, " +
                "ADDRESS(1000, 'Clover_Road', " +
                    "'Happyville', " +
                    "'CA', '90566'), " +
                "COF_ARRAY('Colombian', " +
                    "'French_Roast', " +
                    "'Espresso', " + 
                    "'Colombian_Decaf', " +
                    "'French_Roast_Decaf'), " +
                "(SELECT OID FROM MANAGERS " +
                "WHERE MGR_ID = 000003))";
            stmt.addBatch(insertStore5);
            int [] updateCounts = stmt.executeBatch();
            ResultSet rs = stmt.executeQuery(
                "SELECT * FROM STORES");
            System.out.println("Table STORES after insertion:");
            System.out.println("STORE_NO   " + "LOCATION   " +
                "COF_TYPE   " + "MGR");
            while (rs.next()) {
                int storeNo = rs.getInt("STORE_NO");
                Struct location = (Struct)rs.getObject("LOCATION");
                Object[] locAttrs = location.getAttributes();
                Array coffeeTypes = rs.getArray("COF_TYPE");
                String[] cofTypes = (String[])coffeeTypes.getArray();
                Ref managerRef = rs.getRef("MGR");
                PreparedStatement pstmt = con.prepareStatement(
                    "SELECT MANAGER " +
                    "FROM MANAGERS " +
                    "WHERE OID = ?");
                pstmt.setRef(1, managerRef);
                ResultSet rs2 = pstmt.executeQuery();
                rs2.next();
                Struct manager = (Struct)rs2.getObject("MANAGER");
                Object[] manAttrs = manager.getAttributes();
                System.out.print(storeNo + "   ");
                System.out.print(
                    locAttrs[0] + " " +
                    locAttrs[1] + " " +
                    locAttrs[2] + ", " +
                    locAttrs[3] + " " +
                    locAttrs[4] + " ");
                for (int i = 0; i < cofTypes.length; i++)
                    System.out.print( cofTypes[i] + " ");
                System.out.println(
                    manAttrs[1] + ", " +
                    manAttrs[2]);
                rs2.close();
                pstmt.close();
            }
            rs.close();
        } catch(BatchUpdateException b) {
            System.err.println("-----BatchUpdateException-----");
            System.err.println("SQLState:  " + b.getSQLState());
            System.err.println("Message:  " + b.getMessage());
            System.err.println("Vendor:  " + b.getErrorCode());
            System.err.print("Update counts:  ");
            int [] updateCounts = b.getUpdateCounts();
            for (int i = 0; i < updateCounts.length; i++) {
                System.err.print(updateCounts[i] + "   ");
            }
            System.err.println("");
        } catch(SQLException ex) {
            System.err.println("SQLException: " + ex.getMessage());
            System.err.println("SQLState:  " + ex.getSQLState());
            System.err.println("Message:  " + ex.getMessage());
            System.err.println("Vendor:  " + ex.getErrorCode());
        } finally {
            if (stmt != null) { stmt.close(); }
                JDBCTutorialUtilities.closeConnection(con);
            }
        }
    }
}

Java 中文官方教程 2022 版(三十六)(3)https://developer.aliyun.com/article/1488074

相关文章
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
361 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
3月前
|
Oracle Java 关系型数据库
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
305 2
|
8月前
|
消息中间件 Java 数据库
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8410 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8月前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
133 4
|
8月前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
145 1
|
9月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
556 26
|
8月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
415 0
|
9月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
9月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)

热门文章

最新文章