Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本引入的改进,并可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言功能的摘要,请参见Java语言变更。
有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息,请参见JDK发行说明。
本页面描述了JDBC教程中使用的所有表以及如何创建它们:
COFFEES
表存储了The Coffee Break可供销售的咖啡信息:
COF_NAME |
SUP_ID |
PRICE |
SALES |
TOTAL |
---|---|---|---|---|
哥伦比亚咖啡 | 101 | 7.99 | 0 | 0 |
法式烘焙 | 49 | 8.99 | 0 | 0 |
浓缩咖啡 | 150 | 9.99 | 0 | 0 |
哥伦比亚无咖啡因 | 101 | 8.99 | 0 | 0 |
法式烘焙无咖啡因 | 49 | 9.99 | 0 | 0 |
以下描述了COFFEES
表中的每个列:
COF_NAME
:存储咖啡名称。具有SQL类型VARCHAR
,最大长度为32个字符。由于每种类型的咖啡的名称不同,所以名称唯一地标识特定的咖啡,也作为主键。SUP_ID
:存储标识咖啡供应商的编号。具有SQL类型INTEGER
。它被定义为引用SUPPLIERS
表中SUP_ID
列的外键。因此,数据库管理系统将强制该列中的每个值与SUPPLIERS
表中相应列中的值之一匹配。PRICE
:存储每磅咖啡的成本。具有SQL类型FLOAT
,因为它需要存储带有小数点的值。(请注意,货币值通常存储在SQL类型DECIMAL
或NUMERIC
中,但由于不同数据库管理系统之间的差异以及为了避免与早期版本的JDBC不兼容,教程使用更标准的类型FLOAT
。)SALES
:存储本周销售的咖啡磅数。具有SQL类型INTEGER
。TOTAL
:存储迄今为止销售的咖啡磅数。具有SQL类型INTEGER
。SUPPLIERS
表存储每个供应商的信息:
SUP_ID |
SUP_NAME |
STREET |
CITY |
STATE |
ZIP |
---|---|---|---|---|---|
101 | Acme, Inc. | 99 Market Street | Groundsville | CA | 95199 |
49 | Superior Coffee | 1 Party Place | Mendocino | CA | 95460 |
150 | The High Ground | 100 Coffee Lane | Meadows | 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 | Colombian | 101 | 0 | 2006_04_01 |
1234 | French_Roast | 49 | 0 | 2006_04_01 |
1234 | Espresso | 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 | 大杯 | 00456 | 28 | 2006_04_01 |
00001235 | 小杯 | 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 | 咖啡机 | 08732 | 5 | 2006_04_01 |
00004490 | 咖啡研磨机 | 08732 | 9 | 2006_04_01 |
00004495 | 意式咖啡机 | 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 | Mendocino | 3450 | 2005 | 5455 |
33002 | Seattle | 4699 | 3109 | 7808 |
10040 | 旧金山 | 5386 | 2841 | 8227 |
32001 | 波特兰 | 3147 | 3579 | 6726 |
10042 | 旧金山 | 2863 | 1874 | 4710 |
10024 | 萨克拉门托 | 1987 | 2341 | 4328 |
10039 | 卡梅尔 | 2691 | 1121 | 3812 |
10041 | 洛杉矶 | 1533 | 1007 | 2540 |
33005 | 奥林匹亚 | 2733 | 1550 | 4283 |
33010 | 西雅图 | 3210 | 2177 | 5387 |
10035 | 旧金山 | 1922 | 1056 | 2978 |
10037 | 洛杉矶 | 2143 | 1876 | 4019 |
10034 | 圣何塞 | 1234 | 1032 | 2266 |
32004 | 尤金 | 1356 | 1112 | 2468 |
以下描述了COFFEE_HOUSES
表中的每一列:
STORE_ID
:存储标识咖啡馆的数字。它表示咖啡馆所在的州,其中包括咖啡馆位于加利福尼亚州的州。例如,以10开头的值表示州是加利福尼亚州。以32开头的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创建表。
要创建与教程示例代码一起使用的表,请在目录<JDBC教程目录>
中运行以下命令:
ant setup
此命令运行多个Ant目标,包括以下目标build-tables
(来自build.xml
文件):
<target name="build-tables" description="创建数据库表"> <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任务参数指定了值:
参数 | 描述 |
---|---|
driver |
您的JDBC驱动的完全限定类名。此示例使用org.apache.derby.jdbc.EmbeddedDriver 用于Java DB,以及com.mysql.cj.jdbc.Driver 用于MySQL Connector/J。 |
url |
数据库连接URL,您的DBMS JDBC驱动程序用于连接数据库。 |
userid |
您DBMS中一个有效用户的名称。 |
password |
userid 中指定的用户的密码。 |
classpathref |
包含driver 指定的类的JAR文件的完整路径名 |
delimiter |
用于分隔SQL语句的字符串或字符。此示例使用分号 (; )。 |
autocommit |
布尔值;如果设置为false ,则所有SQL语句将作为一个事务执行。 |
onerror |
当语句失败时执行的操作;可能的值为continue 、stop 和abort 。值abort 指定如果发生错误,则事务将被中止。 |
示例将这些参数的值存储在一个单独的文件中。构建文件build.xml
使用import
任务检索这些值:
<import file="${ANTPROPERTIES}"/>
transaction
元素指定包含要执行的SQL语句的文件。文件create-tables.sql
包含创建本页上描述的所有表的SQL语句。例如,以下摘录自该文件的内容创建了SUPPLIERS
和COFFEES
两个表:
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
的目标,用于删除教程中使用的表。在运行build-tables
目标之前,setup
目标将运行drop-tables
。
下面的方法SuppliersTable.createTable
创建了SUPPLIERS
表格:
public void createTable() throws SQLException { String createString = "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))"; try (Statement stmt = con.createStatement()) { stmt.executeUpdate(createString); } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }
下面的方法CoffeesTable.createTable
创建了COFFEES
表格:
public void createTable() throws SQLException { String createString = "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))"; try (Statement stmt = con.createStatement()) { stmt.executeUpdate(createString); } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }
在这两个方法中,con
是一个Connection
对象,dbName
是你要创建表格的数据库的名称。
要执行SQL查询,例如String
createString
指定的查询,需要使用Statement
对象。要创建Statement
对象,请从现有的Connection
对象调用方法Connection.createStatement
。要执行SQL查询,请调用方法Statement.executeUpdate
。
所有的Statement
对象在创建它们的连接关闭时会被关闭。但是,最好的编码实践是在使用完Statement
对象后显式关闭它们。这可以立即释放语句使用的任何外部资源。通过调用方法Statement.close
来关闭语句。将此语句放在finally
块中,以确保即使程序流因抛出异常(如SQLException
)而中断,它也会关闭。
注意:在创建SUPPLIERS
表之前,您必须创建COFFEES
表,因为COFFEES
包含一个外键SUP_ID
,它引用了SUPPLIERS
表。
同样地,您可以使用Apache Ant或JDBC API向表格中插入数据。
除了创建本教程中使用的表格之外,命令ant setup
还会填充这些表格。该命令运行Ant目标populate-tables
,该目标运行SQL脚本populate-tables.sql
。
以下是从populate-tables.sql
中提取的填充SUPPLIERS
和COFFEES
表的摘录:
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);
下面的方法SuppliersTable.populateTable
向表格中插入数据:
public void populateTable() throws SQLException { try (Statement stmt = con.createStatement()) { stmt.executeUpdate("insert into SUPPLIERS " + "values(49, 'Superior Coffee', '1 Party Place', " + "'Mendocino', 'CA', '95460')"); stmt.executeUpdate("insert into SUPPLIERS " + "values(101, 'Acme, Inc.', '99 Market Street', " + "'Groundsville', 'CA', '95199')"); stmt.executeUpdate("insert into SUPPLIERS " + "values(150, 'The High Ground', '100 Coffee Lane', " + "'Meadows', 'CA', '93966')"); } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }
下面的方法CoffeesTable.populateTable
向表格中插入数据:
public void populateTable() throws SQLException { try (Statement stmt = con.createStatement()) { stmt.executeUpdate("insert into COFFEES " + "values('Colombian', 00101, 7.99, 0, 0)"); stmt.executeUpdate("insert into COFFEES " + "values('French_Roast', 00049, 8.99, 0, 0)"); stmt.executeUpdate("insert into COFFEES " + "values('Espresso', 00150, 9.99, 0, 0)"); stmt.executeUpdate("insert into COFFEES " + "values('Colombian_Decaf', 00101, 8.99, 0, 0)"); stmt.executeUpdate("insert into COFFEES " + "values('French_Roast_Decaf', 00049, 9.99, 0, 0)"); } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }