设置表格

本页描述了 JDBC 教程中使用的所有表以及如何创建它们:

COFFEES Table

COFFEES表存储有关可在 The Coffee Break 出售的咖啡的信息:

COF_NAMESUP_IDPRICESALESTOTAL
Colombian1017.9900
French_Roast498.9900
Espresso1509.9900
Colombian_Decaf1018.9900
French_Roast_Decaf499.9900

下面介绍了COFFEES表中的每个列:

  • COF_NAME:存储咖啡名称。保留 SQL 类型为VARCHAR的值,最大 Long 度为 32 个字符。因为每种出售的咖啡的名称都不相同,所以该名称唯一地标识特定的咖啡并用作主键。

  • SUP_ID:存储标识咖啡供应商的编号。保留 SQL 类型为INTEGER的值。它被定义为引用SUPPLIERS表中的SUP_ID列的外键。因此,DBMS 将强制此列中的每个值与SUPPLIERS表中相应列中的值之一匹配。

  • PRICE:存储每磅咖啡的成本。保留 SQL 类型为FLOAT的值,因为它需要保留带小数点的值。 (请注意,货币值通常存储在 SQL 类型DECIMALNUMERIC中,但是由于 DBMS 之间存在差异,并且为了避免与 JDBC 的早期版本不兼容,本教程使用了更标准的类型FLOAT.)

  • SALES:存储当前一周出售的咖啡磅数。保留 SQL 类型为INTEGER的值。

  • TOTAL:存储迄今为止出售的咖啡磅数。保留 SQL 类型为INTEGER的值。

SUPPLIERS Table

SUPPLIERS存储有关每个供应商的信息:

SUP_IDSUP_NAMESTREETCITYSTATEZIP
101Acme, Inc.99 市场街GroundsvilleCA95199
49Superior Coffee1 聚会场所MendocinoCA95460
150高地100 咖啡巷MeadowsCA93966

下面介绍了SUPPLIERS表中的每个列:

  • SUP_ID:存储标识咖啡供应商的编号。保留 SQL 类型为INTEGER的值。它是此表中的主键。

  • SUP_NAME:存储咖啡供应商的名称。

  • STREETCITYSTATEZIP:这些列存储咖啡供应商的地址。

COF_INVENTORY Table

表格COF_INVENTORY存储有关每个仓库中存储的咖啡量的信息:

WAREHOUSE_IDCOF_NAMESUP_IDQUANDATE_VAL
1234House_Blend4902006_04_01
1234House_Blend_Decaf4902006_04_01
1234Colombian10102006_04_01
1234French_Roast4902006_04_01
1234Espresso15002006_04_01
1234Colombian_Decaf10102006_04_01

下面介绍了COF_INVENTORY表中的每个列:

  • WAREHOUSE_ID:存储标识仓库的编号。

  • COF_NAME:存储特定类型的咖啡的名称。

  • SUP_ID:存储标识供应商的编号。

  • QUAN:存储一个数字,指示可用的商品数量。

  • DATE:存储时间戳值,该值指示上次更新该行的时间。

MERCH_INVENTORY Table

MERCH_INVENTORY存储有关库存中非咖啡商品数量的信息:

ITEM_IDITEM_NAMESUP_IDQUANDATE
00001234Cup_Large00456282006_04_01
00001235Cup_Small00456362006_04_01
00001236Saucer00456642006_04_01
00001287Carafe00456122006_04_01
00006931Carafe0092732006_04_01
00006935PotHolder00927882006_04_01
00006977Napkin009271082006_04_01
00006979Towel00927242006_04_01
00004488CofMaker0873252006_04_01
00004490CofGrinder0873292006_04_01
00004495EspMaker0873242006_04_01
00006914Cookbook00927122006_04_01

下面介绍了MERCH_INVENTORY表中的每个列:

  • ITEM_ID:存储用于标识项 Object 数字。

  • ITEM_NAME:存储项 Object 名称。

  • SUP_ID:存储标识供应商的编号。

  • QUAN:存储一个数字,指示该项目可用的数量。

  • DATE:存储时间戳值,该值指示上次更新该行的时间。

COFFEE_HOUSES Table

COFFEE_HOUSES表存储了咖啡馆的位置:

STORE_IDCITYCOFFEEMERCHTOTAL
10023Mendocino345020055455
33002Seattle469931097808
10040SF538628418227
32001Portland314735796726
10042SF286318744710
10024Sacramento198723414328
10039Carmel269111213812
10041LA153310072540
33005Olympia273315504283
33010Seattle321021775387
10035SF192210562978
10037LA214318764019
10034San_Jose123410322266
32004Eugene135611122468

下面介绍了COFFEE_HOUSES表中的每个列:

  • STORE_ID:存储标识咖啡馆的数字。除其他事项外,它指示咖啡馆所在的状态。以 10 开头的值表示该 State 为加利福尼亚 State。以 32 开头的STORE_ID值表示俄勒冈 State,以 33 开头的STORE_ID值表示华盛顿 State。

  • CITY:存储咖啡馆所在城市的名称。

  • COFFEE:存储一个数字,指示出售的咖啡量。

  • MERCH:存储一个数字,指示已售商品的数量。

  • TOTAL:存储一个数字,指示出售的咖啡和商品的总量。

DATA_REPOSITORY Table

表 DATA_REPOSITORY 存储 URL,这些 URL 引用了 The Coffee Break 的文档和其他感兴趣的数据。脚本populate_tables.sql不会向该表添加任何数据。下面介绍了此表中的每个列:

  • DOCUMENT_NAME:存储标识 URL 的字符串。

  • URL:存储 URL。

Creating Tables

您可以使用 Apache Ant 或 JDBC API 创建表。

使用 Apache Ant 创建表

要创建与教程示例代码一起使用的表,请在目录<JDBC tutorial directory>中运行以下命令:

ant setup

此命令运行多个 Ant 目标,包括以下目标build-tables(来自build.xml文件):

<target name="build-tables"
  description="Create database tables">
  <sql
    driver="${DB.DRIVER}"
    url="${DB.URL}"
    userid="${DB.USER}"
    password="${DB.PASSWORD}"
    classpathref="CLASSPATH"
    delimiter="${DB.DELIMITER}"
    autocommit="false" onerror="abort">
    <transaction src=
  "./sql/${DB.VENDOR}/create-tables.sql"/>
  </sql>
</target>

该示例为以下sql Ant 任务参数指定值:

ParameterDescription
driverJDBC 驱动程序的全限定类名。此示例对 Java DB 使用org.apache.derby.jdbc.EmbeddedDriver,对于 MySQL Connector/J 使用com.mysql.jdbc.Driver
urlDBMS JDBC 驱动程序用来连接数据库的数据库连接 URL。
useridDBMS 中有效用户的名称。
passworduserid中指定的用户密码
classpathref包含driver中指定的类的 JAR 文件的完整路径名
delimiter分隔 SQL 语句的字符串 或字符。本示例使用分号(;)。
autocommit布尔值;如果设置为false,则所有 SQL 语句均作为一个事务执行。
onerror语句失败时执行的操作;可能的值为continuestopabort。值abort指定如果发生错误,则事务中止。

该示例将这些参数的值存储在单独的文件中。构建文件build.xml通过import任务检索以下值:

<import file="${ANTPROPERTIES}"/>

transaction元素指定一个包含要执行的 SQL 语句的文件。文件create-tables.sql包含创建此页上描述的所有表的 SQL 语句。例如,此文件的以下摘录创建表SUPPLIERSCOFFEES

create table SUPPLIERS
    (SUP_ID integer NOT NULL,
    SUP_NAME varchar(40) NOT NULL,
    STREET varchar(40) NOT NULL,
    CITY varchar(20) NOT NULL,
    STATE char(2) NOT NULL,
    ZIP char(5),
    PRIMARY KEY (SUP_ID));

create table COFFEES
    (COF_NAME varchar(32) NOT NULL,
    SUP_ID int NOT NULL,
    PRICE numeric(10,2) NOT NULL,
    SALES integer NOT NULL,
    TOTAL integer NOT NULL,
    PRIMARY KEY (COF_NAME),
    FOREIGN KEY (SUP_ID)
        REFERENCES SUPPLIERS (SUP_ID));

注意 :文件build.xml包含另一个名为drop-tables的目标,该目标删除了教程使用的表。 setup目标在运行build-tables目标之前先运行drop-tables

使用 JDBC API 创建表

以下方法SuppliersTable.createTable创建SUPPLIERS表:

public void createTable() throws SQLException {
    String createString =
        "create table " + dbName +
        ".SUPPLIERS " +
        "(SUP_ID integer NOT NULL, " +
        "SUP_NAME varchar(40) NOT NULL, " +
        "STREET varchar(40) NOT NULL, " +
        "CITY varchar(20) NOT NULL, " +
        "STATE char(2) NOT NULL, " +
        "ZIP char(5), " +
        "PRIMARY KEY (SUP_ID))";

    Statement stmt = null;
    try {
        stmt = con.createStatement();
        stmt.executeUpdate(createString);
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    } finally {
        if (stmt != null) { stmt.close(); }
    }
}

以下方法CoffeesTable.createTable创建COFFEES表:

public void createTable() throws SQLException {
    String createString =
        "create table " + dbName +
        ".COFFEES " +
        "(COF_NAME varchar(32) NOT NULL, " +
        "SUP_ID int NOT NULL, " +
        "PRICE float NOT NULL, " +
        "SALES integer NOT NULL, " +
        "TOTAL integer NOT NULL, " +
        "PRIMARY KEY (COF_NAME), " +
        "FOREIGN KEY (SUP_ID) REFERENCES " +
        dbName + ".SUPPLIERS (SUP_ID))";

    Statement stmt = null;
    try {
        stmt = con.createStatement();
        stmt.executeUpdate(createString);
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    } finally {
        if (stmt != null) { stmt.close(); }
    }
}

在这两种方法中,conConnection对象,而dbName是在其中创建表的数据库的名称。

要执行 SQL 查询(例如String createString指定的查询),请使用Statement对象。若要创建Statement对象,请从现有Connection对象中调用方法Connection.createStatement。要执行 SQL 查询,请调用Statement.executeUpdate方法。

关闭所有Statement对象时,将关闭所有创建它们的连接。但是,良好的编码习惯是在完成Statement对象后立即将其关闭。这允许立即释放该语句使用的任何外部资源。通过调用方法Statement.close关闭语句。将此语句放在finally中,以确保即使由于抛出异常(例如SQLException)而中断了正常程序流,该语句也可以关闭。

注意 :您必须在COFFEES之前创建SUPPLIERS表,因为COFFEES包含引用SUPPLIERS的外键SUP_ID

Populating Tables

同样,您可以使用 Apache Ant 或 JDBC API 将数据插入表中。

使用 Apache Ant 填充表

除了创建本教程使用的表之外,命令ant setup还会填充这些表。此命令运行 Ant 目标populate-tables,后者运行 SQL 脚本populate-tables.sql

以下是来自populate-tables.sql的摘录,该摘录填充了表SUPPLIERSCOFFEES

insert into SUPPLIERS values(
    49, 'Superior Coffee', '1 Party Place',
    'Mendocino', 'CA', '95460');
insert into SUPPLIERS values(
    101, 'Acme, Inc.', '99 Market Street',
    'Groundsville', 'CA', '95199');
insert into SUPPLIERS values(
    150, 'The High Ground',
    '100 Coffee Lane', 'Meadows', 'CA', '93966');
insert into COFFEES values(
    'Colombian', 00101, 7.99, 0, 0);
insert into COFFEES values(
    'French_Roast', 00049, 8.99, 0, 0);
insert into COFFEES values(
    'Espresso', 00150, 9.99, 0, 0);
insert into COFFEES values(
    'Colombian_Decaf', 00101, 8.99, 0, 0);
insert into COFFEES values(
    'French_Roast_Decaf', 00049, 9.99, 0, 0);

使用 JDBC API 填充表

以下方法SuppliersTable.populateTable将数据插入表中:

public void populateTable() throws SQLException {

    Statement stmt = null;
    try {
        stmt = con.createStatement();
        stmt.executeUpdate(
            "insert into " + dbName +
            ".SUPPLIERS " +
            "values(49, 'Superior Coffee', " +
            "'1 Party Place', " +
            "'Mendocino', 'CA', '95460')");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".SUPPLIERS " +
            "values(101, 'Acme, Inc.', " +
            "'99 Market Street', " +
            "'Groundsville', 'CA', '95199')");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".SUPPLIERS " +
            "values(150, " +
            "'The High Ground', " +
            "'100 Coffee Lane', " +
            "'Meadows', 'CA', '93966')");
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    } finally {
        if (stmt != null) { stmt.close(); }
    }
}

以下方法CoffeesTable.populateTable将数据插入表中:

public void populateTable() throws SQLException {

    Statement stmt = null;
    try {
        stmt = con.createStatement();
        stmt.executeUpdate(
            "insert into " + dbName +
            ".COFFEES " +
            "values('Colombian', 00101, " +
            "7.99, 0, 0)");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".COFFEES " +
            "values('French_Roast', " +
            "00049, 8.99, 0, 0)");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".COFFEES " +
            "values('Espresso', 00150, 9.99, 0, 0)");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".COFFEES " +
            "values('Colombian_Decaf', " +
            "00101, 8.99, 0, 0)");

        stmt.executeUpdate(
            "insert into " + dbName +
            ".COFFEES " +
            "values('French_Roast_Decaf', " +
            "00049, 9.99, 0, 0)");
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    } finally {
        if (stmt != null) {
          stmt.close();
        }
    }
}