# 设置表 > 原文: [https://docs.oracle.com/javase/tutorial/jdbc/basics/tables.html](https://docs.oracle.com/javase/tutorial/jdbc/basics/tables.html) 此页面描述了 JDBC 教程中使用的所有表以及如何创建它们: * [咖啡表](#coffees) * [供应商表](#suppliers) * [COF_INVENTORY 表](#cof_inventory) * [MERCH_INVENTORY 表](#merch_inventory) * [COFFEE_HOUSES 表](#coffee_houses) * [DATA_REPOSITORY 表](#data_repository) * [创建表格](#create) * [填充表](#populate) `COFFEES`表存储有关咖啡休息时间可供销售的咖啡的信息: | `COF_NAME` | `SUP_ID` | `PRICE` | `SALES` | `TOTAL` | | --- | --- | --- | --- | --- | | 哥伦比亚 | 101 | 7.99 | 0 | 0 | | French_Roast | 49 | 8.99 | 0 | 0 | | 浓咖啡 | 150 | 9.99 | 0 | 0 | | Colombian_Decaf | 101 | 8.99 | 0 | 0 | | French_Roast_Decaf | 49 | 9.99 | 0 | 0 | 以下描述了`COFFEES`表中的每一列: * `COF_NAME`:存储咖啡名称。保存 SQL 类型为`VARCHAR`且最大长度为 32 个字符的值。因为每种类型的咖啡的名称都不同,所以该名称唯一地标识特定的咖啡并且用作主键。 * `SUP_ID`:存储识别咖啡供应商的编号。保存 SQL 类型为`INTEGER`的值。它被定义为引用`SUPPLIERS`表中的`SUP_ID`列的外键。因此,DBMS 将强制执行此列中的每个值与`SUPPLIERS`表中相应列中的某个值匹配。 * `PRICE`:存储每磅咖啡的成本。保存 SQL 类型为`FLOAT`的值,因为它需要保存带小数点的值。 (请注意,货币值通常存储在 SQL 类型`DECIMAL`或`NUMERIC`中,但由于 DBMS 之间存在差异并且为了避免与早期版本的 JDBC 不兼容,本教程使用更标准的类型`FLOAT`。) * `SALES`:存储本周销售的咖啡磅数。保存 SQL 类型为`INTEGER`的值。 * `TOTAL`:存储迄今为止销售的咖啡磅数。保存 SQL 类型为`INTEGER`的值。 `SUPPLIERS`存储有关每个供应商的信息: | `SUP_ID` | `SUP_NAME` | `STREET` | `CITY` | `STATE` | `ZIP` | | --- | --- | --- | --- | --- | --- | | 101 | Acme,Inc。 | 市场街 99 号 | Groundsville | CA | 95199 | | 49 | 高级咖啡 | 1 个派对地点 | 门多西诺 | CA | 95460 | | 150 | 高地 | 100 咖啡巷 | 梅多斯 | CA | 93966 | 以下描述了`SUPPLIERS`表中的每一列: * `SUP_ID`:存储识别咖啡供应商的编号。保存 SQL 类型为`INTEGER`的值。它是此表中的主键。 * `SUP_NAME`:存储咖啡供应商的名称。 * `STREET`,`CITY`,`STATE`和`ZIP`:这些列存储咖啡供应商的地址。 表`COF_INVENTORY`存储有关每个仓库中存储的咖啡量的信息: | `WAREHOUSE_ID` | `COF_NAME` | `SUP_ID` | `QUAN` | `DATE_VAL` | | --- | --- | --- | --- | --- | | 1234 | House_Blend | 49 | 0 | 2006_04_01 | | 1234 | House_Blend_Decaf | 49 | 0 | 2006_04_01 | | 1234 | 哥伦比亚 | 101 | 0 | 2006_04_01 | | 1234 | French_Roast | 49 | 0 | 2006_04_01 | | 1234 | 浓咖啡 | 150 | 0 | 2006_04_01 | | 1234 | Colombian_Decaf | 101 | 0 | 2006_04_01 | 以下描述了`COF_INVENTORY`表中的每一列: * `WAREHOUSE_ID`:存储标识仓库的编号。 * `COF_NAME`:存储特定类型咖啡的名称。 * `SUP_ID`:存储标识供应商的编号。 * `QUAN`:存储一个表示可用商品数量的数字。 * `DATE`:存储时间戳值,指示上次更新行的时间。 表`MERCH_INVENTORY`存储有关库存中非咖啡商品数量的信息: | `ITEM_ID` | `ITEM_NAME` | `SUP_ID` | `QUAN` | `DATE` | | --- | --- | --- | --- | --- | | 00001234 | Cup_Large | 00456 | 28 | 2006_04_01 | | 00001235 | Cup_Small | 00456 | 36 | 2006_04_01 | | 00001236 | 茶托 | 00456 | 64 | 2006_04_01 | | 00001287 | 玻璃水瓶 | 00456 | 12 | 2006_04_01 | | 00006931 | 玻璃水瓶 | 00927 | 3 | 2006_04_01 | | 00006935 | 隔热垫 | 00927 | 88 | 2006_04_01 | | 00006977 | 餐巾 | 00927 | 108 | 2006_04_01 | | 00006979 | 毛巾 | 00927 | 24 | 2006_04_01 | | 00004488 | CofMaker | 08732 | 五 | 2006_04_01 | | 00004490 | CofGrinder | 08732 | 9 | 2006_04_01 | | 00004495 | EspMaker | 08732 | 4 | 2006_04_01 | | 00006914 | 菜谱 | 00927 | 12 | 2006_04_01 | 以下描述了`MERCH_INVENTORY`表中的每一列: * `ITEM_ID`:存储标识项目的编号。 * `ITEM_NAME`:存储项目的名称。 * `SUP_ID`:存储标识供应商的编号。 * `QUAN`:存储一个数字,表示该项目的可用数量。 * `DATE`:存储时间戳值,指示上次更新行的时间。 表`COFFEE_HOUSES`存储咖啡馆的位置: | `STORE_ID` | `CITY` | `COFFEE` | `MERCH` | `TOTAL` | | --- | --- | --- | --- | --- | | 10023 | 门多西诺 | 3450 | 2005 年 | 5455 | | 33002 | 西雅图 | 4699 | 3109 | 7808 | | 10040 | SF | 5386 | 2841 | 8227 | | 32001 | 波特兰 | 3147 | 3579 | 6726 | | 10042 | SF | 2863 | 1874 年 | 4710 | | 10024 | 萨克拉门托 | 1987 年 | 2341 | 4328 | | 10039 | 卡梅尔 | 2691 | 1121 | 3812 | | 10041 | LA | 1533 | 1007 | 2540 | | 33005 | 奥林匹亚 | 2733 | 1550 | 4283 | | 33010 | 西雅图 | 3210 | 2177 | 5387 | | 10035 | SF | 1922 年 | 1056 | 2978 | | 10037 | LA | 2143 | 1876 年 | 4019 | | 10034 | 圣荷西 | 1234 | 1032 | 2266 | | 32004 | 尤金 | 1356 | 1112 | 2468 | 以下描述了`COFFEE_HOUSES`表中的每一列: * `STORE_ID`:存储识别咖啡馆的号码。除其他外,它表示咖啡馆所处的状态。例如,以 10 开头的值表示该州是加利福尼亚州。以 CO 开头的`STORE_ID`值表示俄勒冈州,而以 33 开头的值表示华盛顿州。 * `CITY`:存储咖啡馆所在城市的名称。 * `COFFEE`:存储一个表示已售咖啡量的数字。 * `MERCH`:存储一个表示销售商品数量的数字。 * `TOTAL`:存储一个数字,表示已售出的咖啡和商品的总量。 表 DATA_REPOSITORY 存储引用 The Coffee Break 感兴趣的文档和其他数据的 URL。脚本`populate_tables.sql`不会向此表添加任何数据。以下描述了此表中的每个列: * `DOCUMENT_NAME`:存储标识 URL 的字符串。 * `URL`:存储 URL。 您可以使用 Apache Ant 或 JDBC API 创建表。 ### 使用 Apache Ant 创建表 要创建与教程示例代码一起使用的表,请在目录``中运行以下命令: ```java ant setup ``` 此命令运行多个 Ant 目标,包括以下`build-tables`(来自`build.xml`文件): ```java ``` 该示例指定以下`sql` Ant 任务参数的值: | 参数 | 描述 | | --- | --- | | `driver` | JDBC 驱动程序的完全限定类名。此示例使用`org.apache.derby.jdbc.EmbeddedDriver`表示 Java DB,`com.mysql.jdbc.Driver`表示 MySQL Connector / J. | | `url` | DBMS JDBC 驱动程序用于连接数据库的数据库连接 URL。 | | `userid` | DBMS 中有效用户的名称。 | | `password` | `userid`中指定的用户密码 | | `classpathref` | 包含`driver`中指定的类的 JAR 文件的完整路径名 | | `delimiter` | 用于分隔 SQL 语句的字符串或字符。此示例使用分号(`;`)。 | | `autocommit` | 布尔值;如果设置为`false`,则所有 SQL 语句都作为一个事务执行。 | | `onerror` | 语句失败时要执行的操作;可能的值为`continue`,`stop`和`abort`。值`abort`指定如果发生错误,则中止事务。 | 该示例将这些参数的值存储在单独的文件中。构建文件`build.xml`使用`import`任务检索这些值: ```java ``` `transaction`元素指定包含要执行的 SQL 语句的文件。文件`create-tables.sql`包含创建此页面上描述的所有表的 SQL 语句。例如,以下摘录自此文件创建表`SUPPLIERS`和`COFFEES`: ```java 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](gettingstarted.html)`创建`SUPPLIERS`表: ```java 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](gettingstarted.html)`创建`COFFEES`表: ```java 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(); } } } ``` 在这两种方法中,`con`是`Connection`对象,`dbName`是要在其中创建表的数据库的名称。 要执行 SQL 查询(例如`String` `createString`指定的查询),请使用`Statement`对象。要创建`Statement`对象,请从现有`Connection`对象调用方法`Connection.createStatement`。要执行 SQL 查询,请调用方法`Statement.executeUpdate`。 关闭创建它们的连接时,将关闭所有`Statement`对象。但是,一旦完成它们,就明确关闭`Statement`对象是一种很好的编码实践。这允许立即释放语句正在使用的任何外部资源。通过调用方法`Statement.close`关闭语句。将此语句放在`finally`中以确保即使正常程序流因为抛出异常(例如`SQLException`)而中断也会关闭。 **注**:必须在`COFFEES`之前创建`SUPPLIERS`表,因为`COFFEES`包含一个外键,`SUP_ID`引用`SUPPLIERS`。 同样,您可以使用 Apache Ant 或 JDBC API 将数据插入表中。 ### 使用 Apache Ant 填充表 除了创建本教程使用的表之外,命令`ant setup`还会填充这些表。此命令运行 Ant 目标`populate-tables`,它运行 SQL 脚本`populate-tables.sql`。 以下是填充表`SUPPLIERS`和`COFFEES`的`populate-tables.sql`的摘录: ```java 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`将数据插入表中: ```java 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`将数据插入表中: ```java 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(); } } } ```