1、数据库的应用在日常的生活和工作中可以说是无处不在,无论是一个小型的企业办公自动化系统,还是像中国移动那样的大型运营系统,似乎都离不开数据库。对于大多数应用程序来说,不管它们是 Windows 桌面应用程序,还是 Web应用程序,存储和检索数据都是其核心功能,所以针对数据库的开发已经成为软件开发的一种必备技能。如果说过去是“学好数理化,走遍天下都不怕” ,那么,对于今天的软件开发者而言就是“学好数据库,走到哪儿都不怵” 。本章将向读者介绍如何在 Java Web 中进行数据库应用开发。通过阅读本章,您可以: 了解 JDBC 的结构体系 掌握 JDBC 连接数据库的过程 熟悉 JDBC 的常用 A
2、PI 掌握通过 JDBC 向数据库中添加数据 掌握通过 JDBC 查询数据 掌握通过 JDBC 修改数据库中的数据 掌握通过 JDBC 删除数据库中的数据 掌握进行批处理的方法 掌握 JDBC 在 Java Web 中的应用 1011第第 章章导读Java Web 的数据库操作( 视频讲解:48 分钟)第 10 章 Java Web 的数据库操作19710.1 JDBC 技术视频讲解:光盘TMlx10JDBC 技术.exeJDBC( Java Data Base Connectivity)是 Java 程序与数据库系统通信的标准 API,它定义在 JDK的 API 中,通过 JDBC 技术,J
3、ava 程序可以非常方便地与各种数据库交互,JDBC 在 Java 程序与数据库系统之间架起了一座桥梁。10.1.1 JDBC 简介JDBC 是 Java 程序操作数据库的 API,也是 Java 程序与数据库交互的一门技术。JDBC 是 Java 操作数据库的规范,由一组用 Java 语言编写的类和接口组成,它对数据库的操作提供了基本方法,但对于数据库的细节操作由数据库厂商进行实现。使用 JDBC 操作数据库,需要数据库厂商提供数据库的驱动程序。Java 程序与数据库交互的示意图如图 10.1 所示。通过图 10.1 可以看出,JDBC 在 Java 程序与数据库之间起到了一个桥梁的作用,有
4、了 JDBC 就可以方便地与各种数据库进行交互,不必为某一个特定的数据库制定 专 门 的 访 问 程 序 。 例 如 , 访 问 MySQL 数 据 库 可 以使 用 JDBC 进 行 访 问 , 访 问 SQL Server 同 样 使 用 JDBC。 因 此 , JDBC 对 Java 程 序 员 而 言 , 是 一 套 标 准的 操 作 数 据 库 的 API; 而 对 数 据 库 厂 商 而 言 , 又 是 一 套 标 准 的 模 型 接 口 。10.1.2 JDBC 连接数据库的过程在了解了 JDBC 与数据库后,本节介绍使用 JDBC 操作数据的开发流程,其关键步骤如下。 注册数据
5、库驱动连接数据库前,需要将数据库厂商提供的数据库驱动类注册到 JDBC 的驱动管理器中。通常情况数据库数 据 库 驱 动J D B C A P IJ a v a 程 序图 10.1 Java 程序与数据库交互目前,除 JDBC 访问数据库的方法外, Java 程序也可以通过 Microsoft 提供的 ODBC 来访问数据库。ODBC 通 过 C 语言实现 API,它使用的是 C 语言中的接口,虽然 ODBC 的应用十分广泛,但通过 Java 语言来调用 ODBC 中的 C 代码,在技术实现、安全性、跨平台等方面,仍存在一定的缺点,并且也有一定的难度;而 JDBC 则是纯 Java 语言编写的
6、,通过 Java 程序来调用 JDBC,自然也非常简单。所以,在 Java 领域中,几乎所有的 Java 程序员都是使用 JDBC 来操作数据库。Java Web 从入门到精通(第 2 版)198下,是通过将数据库驱动类加载到 JVM 来实现的。【例 10.1】 加载数据库驱动,注册到驱动管理器。代码如下:Class.forName(“com.mysql.jdbc.Driver“); 构建数据库连接 URL要建立数据库连接,就要构建数据库连接的 URL,这个 URL 由数据库厂商制定,不同的数据库,它的 URL 也有所区别,但都符合一个基本的格式,即“JDBC 协议+IP 地址或域名+端口+
7、数据库名称”。如 MySQL 的数据库连接 URL 的字符串为“jdbc:mysql:/localhost:3306/test” 。 获取 Connection 对象在注册了数据库驱动及构建数据库 URL 后,就可以通过驱动管理器获取数据库的连接Connection。Connection 对象是 JDBC 封装的数据库连接对象,只有创建此对象后,才可以对数据进行相关操作,它的获取方法如下:DriverManager.getConnection(url,username,password);Connection 对象的获取需要用到 DriverManager 对象,DriverManager 的
8、 getConnection()方法通过数据库连接 URL、数据库用户名及数据库密码创建 Connection 对象。【例 10.2】 通 过 JDBC 连 接 MySQL 数 据 库 。 (实例位置:光 盘TMsl101)(1)创建名称为 10.1 的动态 Web 项目,将 MySQL 数据库的驱动包添加至项目的构建路径,构建开发环境。(2)创建程序中的主页 index.jsp,在该页面中加载数据库驱动并创建数据库连接。关键代码如下:在 index.jsp 页面中,首先通过 Class 的 forName()方法加载数据库驱动,然后使用 DriverManager 对象的 getConnec
9、tion()方法获取数据库连接 Connection 对象,最后将获取结果输出到页面中。实例运行结果如图 10.2 所示。10.2 JDBC API视频讲解:光盘TMlx10JDBC API.exeJDBC 是 Java 程 序 操 作 数 据 库 的 标 准 , 它 由 一 组 用 Java 语 言 编 写 的 类 和 接 口 组 成 , Java 通 过 JDBC可 以 对 多 种 关 系 数 据 库 进 行 统 一 访 问 。 所 以 , 学 习 JDBC 需 要 掌 握 JDBC 中 的 类 和 接 口 , 也 就 是 JDBC API。10.2.1 Connection 接口Conn
10、ection 接口位于 java.sql 包中,是与特定数据库的连接会话,只有获得特定数据库的连接对象,才能访问数据库,操作数据库中的数据表、视图和存储过程等。Connection 接口的方法声明及说明如表 10.1 所示。表 10.1 Connection 接口的方法声明及说明方 法 声 明 说 明void close() throws SQLException 立即释放 Connection 对象的数据库连接占用的 JDBC资源,在操作数据库后,应立即调用此方法void commit() throws SQLException提交事务,并释放 Connection 对象当前持有的所有数据库
11、锁。当事务被设置为手动提交模式时,需要调用该方法提交事务如 果 数 据 库 连 接 失 败 ,请 确 认 数 据 库 服 务 是 否 开 启 ,因 为 只有 数 据 库 的 服 务 处 于 开 启 状 态 ,才 能 成 功 地 与 数 据 库 建 立 连 接。 图 10.2 与数据库建立连接Java Web 从入门到精通(第 2 版)200Statement createStatement() throws SQLException 创建一个 Statement 对象来将 SQL 语句发送到数据库,该方法返回 Statement 对象续表 方 法 声 明 说 明boolean getAutoC
12、ommit() throws SQLException 用于判断 Connection 对象是否被设置为自动提交模式,该方法返回布尔值DatabaseMetaData getMetaData() throws SQLException获取 Connection 对象所连接的数据库的元数据DatabaseMetaData 对象,元数据包括关于数据库的表、受支持的 SQL 语法、存储过程、此连接功能等信息int getTransactionIsolation() throws SQLException 获取 Connection 对象的当前事务隔离级别boolean isClosed() thro
13、ws SQLException判断 Connection 对象是否与数据库断开连接,该方法返回布尔值。需要注意的是,如果 Connection 对象与数据库断开连接,则不能再通过 Connection 对象操作数据库boolean isReadOnly() throws SQLException 判 断 Connection 对 象 是 否 为 只 读 模 式 , 该 方 法 返 回 布 尔值PreparedStatement prepareStatement(String sql) throws SQLException将参数化的 SQL 语句预编译并存储在PreparedStatement
14、 对象中,并返回所创建的这个PreparedStatement 对象void releaseSavepoint(Savepoint savepoint) throws SQLException 从 当 前 事 务 中 移 除 指 定 的 Savepoint 和 后 续 Savepoint 对象void rollback() throws SQLException回滚事务,并释放 Connection 对象当前持有的所有数据库锁。注意,该方法需要应用于 Connection 对象的手动提交模式中void rollback(Savepoint savepoint) throws SQLExcept
15、ion 回滚事务,针对 Savepoint 对象之后的更改void setAutoCommit(boolean autoCommit) throws SQLException设置 Connection 对象的提交模式,如果参数autoCommit 的值设置为 true,Connection 对象则为自动提交模式;如果参数 autoCommit 的值设置为false,Connection 对象则为手动提交模式void setReadOnly(boolean readOnly) throws SQLException 将 Connection 对象的连接模式设置为只读,该方法用于对数据库进行优化S
16、avepoint setSavepoint() throws SQLException 在当前事务中创建一个未命名的保留点,并返回这个保留点对象Savepoint setSavepoint(String name) throws SQLException 在 当 前 事 务 中 创 建 一 个 指 定 名 称 的 保 留 点 , 并 返 回 这 个保 留 点 对 象void setTransactionIsolation(int level) throws SQLException 设置 Connection 对象的事务隔离级别表 10.1 中所列出的方法均为 Connection 接口的常用
17、方法,其更多方法的声明及 说明请参照J2SE 的 API。第 10 章 Java Web 的数据库操作20110.2.2 DriverManager 类使用 JDBC 操作数据库,需要使用数据库厂商提供的驱动程序,通过驱动程序可以与数据库进行交互。DriverManager 类主要作用于用户及驱动程序之间,它是 JDBC 中的管理层,通过DriverManager 类可以管理数据库厂商提供的驱动程序,并建立应用程序与数据库之间的连接,其方法声明及说明如表 10.2 所示。表 10.2 DriverManager 类的方法声明及说明方 法 声 明 说 明public static void de
18、registerDriver(Driver driver) throws SQLException 从 DriverManager 的管理列表中删除一个驱动程序。参数 driver 为要删除的驱动对象public static Connection getConnection(String url) throws SQLException 根据指定数据库连接 URL,建立与数据库连接Connection。参数 url 为数据库连接 URLpublic static Connection getConnection(String url,Properties info) throws SQLEx
19、ception根据 指 定 数 据 库 连 接 URL 及 数 据 库 连 接 属 性 信息 建 立 数 据 库连接 Connection。参数 url 为数据库连接 URL,参数 info 为数据库连接属性public static Connection getConnection(String url, String user, String password) throws SQLException根据指定数据库连接 URL、用户名及密码建立数据库连接 Connection。参数 url 为数据库连接 URL,参数 user 为连接数据库的用户名,参数 password 为连接数据库的密
20、码public static Enumeration getDrivers() 获取当前 DriverManager 中已加载的所有驱动程序,它的返回值为 Enumerationpublic static void registerDriver(Driver driver) throws SQLException 向 DriverManager 注 册 一 个 驱 动 对 象 , 参 数driver 为要注册的驱动10.2.3 Statement 接口在创建了数据库连接之后,就可以通过程序来调用 SQL 语句对数据库进行操作,在 JDBC 中Statement 接口封装了这些操作。Statem
21、ent 接口提供了执行语句和获取查询结果的基本方法,其方法声明及说明如表 10.3 所示。表 10.3 Statement 接口的方法声明及说明方 法 声 明 说 明void addBatch(String sql) throws SQLException 将 SQL 语句添加到 Statement 对象的当前命令列表中,该方法用于 SQL 命令的批处理void clearBatch() throws SQLException 清空 Statement 对象中的命令列表void close() throws SQLException 立即释放 Statement 对象的数据库和 JDBC 资源
22、,而不是等待该对象自动关闭时发生此操作Java Web 从入门到精通(第 2 版)202boolean execute(String sql) throws SQLException 执行指定的 SQL 语句。如果 SQL 语句返回结果,该方法返回 true,否则返回 falseint executeBatch() throws SQLException 将一批 SQL 命令提交给数据库执行,返回更新计数组成的数组ResultSet executeQuery(String sql) throws SQLException 执行查询类型(select)的 SQL 语句,该方法返回查询所获取的结果
23、集 ResultSet 对象续表 方 法 声 明 说 明executeUpdate int executeUpdate(String sql) throws SQLException执行 SQL 语句中 DML 类型(insert、 update、delete)的 SQL 语句,返回更新所影响的行数Connection getConnection() throws SQLException 获取生成 Statement 对象的 Connection 对象boolean isClosed() throws SQLException判断 Statement 对象是否已被关闭,如果被关闭,则不能再调
24、用该 Statement 对象执行 SQL 语句,该方法返回布尔值10.2.4 PreparedStatement 接口Statement 接口封装了 JDBC 执行 SQL 语句的方法,它可以完成 Java 程序执行 SQL 语句的操作,但在实际开发过程中,SQL 语句往往需要将程序中的变量做查询条件参数等。使用 Statement 接口进行操作过于烦琐,而且存在安全方面的缺陷,针对这一问题,JDBC API 中封装了 Statement 的扩展PreparedStatement 对象。PreparedStatement 接口继承于 Statement 接口,它拥有 Statement 接口
25、中的方法,而且PreparedStatement 接 口 针 对 带 有 参 数 SQL 语 句 的 执 行 操 作 进 行 了 扩 展 。 应 用 于 PreparedStatement 接 口中 的 SQL 语 句 , 可 以 使 用 占 位 符 “?”来 代 替 SQL 语 句 中 的 参 数 , 然 后 再 对 其 进 行 赋 值 。PreparedStatement 接口的方法声明及说明如表 10.4 所示。表 10.4 PreparedStatement 接口的方法声明及说明方 法 声 明 说 明void setBinaryStream (int parameterIndex, I
26、nputStream x)throws SQLException 将输入流 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引void setBoolean(int parameterIndex,boolean x) throws SQLException 将布尔值 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引void setByte(int parameterIndex, byte x)throws SQLException 将 byte 值 x 作为 SQL 语句中的参数值, parameterIndex 为参数位置的索引v
27、oid setDate (int parameterIndex, Date x) throws SQLException将 java.sql.Date 值 x 作 为 SQL 语 句 中 的 参 数 值 , parameterIndex 为参数位置的索引void setDouble(int parameterIndex, double x) 将 double 值 x 作 为 SQL 语 句 中 的 参 数 值 , parameterIndex 为 参 数 位 置 的 索第 10 章 Java Web 的数据库操作203throws SQLException 引void setFloat (in
28、t parameterIndex, float x) throws SQLException将 float 值 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引void setInt(int parameterIndex, int x)throws SQLException 将 int 值 x 作为 SQL 语句中的参数值, parameterIndex 为参数位置的索引void setInt(int parameterIndex, long x)throws SQLException将 long 值 x 作为 SQL 语句中的参数值,parameterInde
29、x 为参数位置的索引续表 方 法 声 明 说 明void setObject(int parameterIndex, Object x) throws SQLException将 Object 对象 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引void setShort(int parameterIndex, short x) throws SQLException将 short 值 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引void setString(int parameterIndex, String x) thr
30、ows SQLException将 String 值 x 作 为 SQL 语 句 中 的 参 数 值 , parameterIndex 为 参 数 位 置 的 索 引void setTimestamp (int parameterIndex, Timestamp x)throws SQLException将 Timestamp 值 x 作为 SQL 语句中的参数值,parameterIndex 为参数位置的索引在 实 际 的 开 发 过 程 中 , 如 果 涉 及 向 SQL 语 句 传 递 参 数 , 最 好 使 用 PreparedStatement 接 口 实 现 。 因 为使 用 Pr
31、eparedStatement 接口,不仅可以提高 SQL 的执行效率,而且还可以避免 SQL 语句的注入式攻击。10.2.5 ResultSet 接口执行 SQL 语句的查询语句会返回查询的结果集,在 JDBC API 中,使用 ResultSet 对象接收查询结果集。ResultSet 接口位于 java.sql 包中,封装了数据查询的结果集。 ResultSet 对象包含了符合 SQL 语句的所有行,针对 Java 中的数据类型提供了一套 getXXX()方法,通过这些方法可以获取每一行中的数据。除此之外,ResultSet 还提供了光标的功能,通过光标可以自由定位到某一行中的数据,其方
32、法声明及说明如表 10.5 所示。表 10.5 ResultSet 接口的方法声明及说明方 法 声 明 说 明boolean absolute(int row) throws SQLException 将光标移动到 ResultSet 对象的给定行编号,参数 row 为行编号void afterLast() throws SQLException 将光标移动到 ResultSet 对象的最后一行之后,如果结果集中不包含任何行,则该方法无效void beforeFirst() throws SQLException 立即释放 ResultSet 对象的数据库和 JDBC 资源void delet
33、eRow() throws SQLException 从 ResultSet 对象和底层数据库中删除当前行boolean first() throws SQLException 将光标移动到 ResultSet 对象的第一行Java Web 从入门到精通(第 2 版)204InputStream getBinaryStream(String columnLabel)throws SQLException以 byte 流的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称Date getDate(String columnLabel)throws SQL
34、Exception 以 java.sql.Date 的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称double getDouble(String columnLabel)throws SQLException 以 double 的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称float getFloat(String columnLabel)throws SQLException 以 float 的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称续表 方 法
35、 声 明 说 明int getInt(String columnLabel)throws SQLException 以 int 的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称String getString(String columnLabel)throws SQLException 以 String 的方式获取 ResultSet 对象当前行中指定列的值,参数 columnLabel 为列名称boolean isClosed() throws SQLException 判断当前 ResultSet 对象是否已关闭boolean last() t
36、hrows SQLException 将光标移动到 ResultSet 对象的最后一行boolean next() throws SQLException 将光标位置向后移动一行,如果移动的新行有效则返回true,否则返回 falseboolean previous() throws SQLException 将光标位置向前移动一行,如果移动的新行有效则返回true,否则返回 false10.3 JDBC 操作数据库视频讲解:光盘TMlx10JDBC 操作数据库.exe在了解了 JDBC API 后,就可以通过 JDBC API 来操作数据库,实现对数据库的 CRUD 操作。10.3.1 添加
37、数据通过 JDBC 向数据库添加数据,可以使用 INSERT 语句实现插入数据的 SQL 语句,对于 SQL 语句中的参数可以用占位符“?”代替,然后通过 PreparedStatement 对其赋值并执行 SQL。【例 10.3】 创 建 Web 项 目 , 通 过 JDBC 实 现 图 书 信 息 添 加 功 能 。(实例位置:光盘TMsl102)(1)在 MySQL 数据库中创建图书信息表 tb_books,其结构如图 10.3 所示。图 10.3 tb_books 表结构第 10 章 Java Web 的数据库操作205(2)创建名称为 Book 的类,用于封装图书对象信息。关键代码如
38、下:public class Book private int id; /编号private String name; /图书名称private double price; /价格private int bookCount; /数量private String author; /作者public int getId() return id;public void setId(int id) this.id = id;/省略部分 setXXX()与 getXXX()方法(3)创建 index.jsp 页面,它是程序中的主页,用于放置添加图书信息所需要的表单,该表单提交到 AddBook.jsp 页面进行处理。关键代码如下:添加图书信息图书名称:价 格:数 量:作 者: