网站设置会员网站怎样优化seo
7. 3 使用 JDBC 操作数据库
JDBC 的接口分为两个层次: 一个是面向程序开发人员的 JDBC API; 另一个是底层的JDBC 驱动器 API。 JDBC 接口如图 7-11 所示。
Java Database Connectivity (JDBC) 是一个标准的 Java API, 由一组类和接口组成, Java应用程序开发人员使用它来访问数据库和执行 SQL 语句。 JDBC API 主要包括 6 种接口, 见
表 7-1。
7. 3. 1 使用 JDBC 访问数据库的过程
JDBC 访问数据库可以分为连接数据库和操作数据库两个步骤。 图 7-12 给出了用简单的 JDBC 模型进行连接、 执行和获取数据的过程。
1. JDBC 连接数据库
JDBC 连接数据库分为加载驱动程序和建立连接两个步骤。加载驱动程序为了与特定的数据源或者数据库相连,JDBC 必须加载相应的驱动程序。 驱动程序可以是 JDBC - ODBC 桥驱动程序、 JDBC 通过网络协议的驱动程序, 或者是由数据库厂商提供的驱动程序。各种数据库的连接方法见表 7-2。
【例 7-1】 下面的例子测试数据是否连接成功。
首先安装数据库 MySQL, 本书选择的安装的版本为 MySQL - 5. 1. 24, 在安装 MySQL 之前首先安装 . NET Framewrok 4。 图 7-13 所示为 . NET Framewrok 4 安装界面。 图 7-14 所示为
MySQL 安装界面。MySQL 安装完成以后, 首先将本章的 db. txt 导入到 MySQL 中, 登录 MySQL 命令行客户端, 使用下列命令:
Source 绝对路径\db. txt
创建 testconnection. jsp 网页文件,代码如下:
< % @ pagecontentType = " text / html; charset = gb2312" language = " java" errorPage = " " % >
< % @ page import = " java. sql. ∗ " % >
< ! DOCTYPE HTML PUBLIC " - / / W3C / / DTD HTML 4. 01 Transitional / / EN" >
< html >
< head >
< meta http - equiv = " Content - Type" content = " text / html; charset = gb2312" >
< title > test connection < / title >
< / head >
< body >
< %
String url = " jdbc:mysql: / / localhost / ch10" ;
String userName = " root" ;
String password = " root" ;
Connection conn = null;
try {
Class. forName(" com. mysql. jdbc. Driver" );
} catch(ClassNotFoundException e) {
out. println("加载驱动器类时出现异常" );
}try {
conn = null;
conn = DriverManager. getConnection(url, userName, password);
} catch(SQLException e) {
out. println("连接数据库的过程中出现 SQL 异常" );
} if (conn = = null)
out. println("连接数据库失败" );
else
out. println("连接数据库成功" );
try {
conn. close( );
} catch (SQLException e) {
out. println("关闭数据库连接时出现 SQL 异常" );
} %
>
< / body >
< / html >
在 Tomcat 服务器下测试 testconnection. jsp, 运行结果如图 7-15 所示。
2. JDBC 操作数据库
JDBC 在连接数据库之后, 就可以对数据库中的数据库进行操作了, 可按以下步骤进行。在 Java 程序中通过 JDBC 操作数据库一般分为以下几个步骤。
(1) 将数据库的 JDBC 驱动加载到 classpath 中, 在给予 Java EE 的 Web 应用实际开发过程中, 通常要把目标数据库产品的 JDBC 驱动复制到 WEB - INF / lib 下。
(2) 加载 JDBC 驱动, 并将其注册到 DriverManager 中。 下面是一些主流数据库的 JDBC
驱动加载注册的代码:
Oracle8 / 8i / 9i 数据库(thin 模式)
Class. forName(" oracle. jdbc. driver. OracleDriver" ). newInstance( );
SQL7. 0 / 2000 数据库
Class. forName(" com. microsoft. jdbc. sqlserver. SQLServerDriver" ). newInstance( );
DB2 数据库
Class. forName(" com. ibm. db2. jdbc. app. DB2Driver" ). newInstance( );
Informix 数据库
Class. forName(" com. informix. jdbc. IfxDriver" ). newInstance( );
Sybase 数据库
Class. forName(" com. sybase. jdbc. SybDriver" ). newInstance( );
MySQL 数据库
Class. forName(" com. mysql. jdbc. Driver" ). newInstance( );
PostgreSQL 数据库
Class. forName(" org. postgresql. Driver" ). newInstance( );
Access 数据库
Class. forName(" sun. jdbc. odbc. JdbcOdbcDriver" ). newInstance( );
(3) 建立数据库连接, 取得 Connection 对象, 一些主流数据库代码如下:
Oracle8 / 8i / 9i 数据库 (thin 模式)String url = " jdbc:oracle:thin:@ localhost:1521:orcl" ; String user = " scott" ; String password = " tiger" ; Connection conn = DDriverManager. getConnection(url,user,password);
SQL7. 0 / 2000 数据库
String url = " jdbc:microsoft:sqlserver: / / localhost:1433;DatabaseName = pubs" ;
String user = " sa" ;tring password = " " ;
Connection conn = DDriverManager. getConnection(url,user,password);
DB2 数据库
String url = " jdbc:db2: / / localhost:5000 / sample" ; String user = " admin" ; String password
= " " ;
Connection conn = DDriverManager. getConnection(url,user,password);
Informix 数据库
String url = " jdbc:informix - sqli / / localhost:1533 / test DB:INFORMIXSERVER = myserver;
user = testuser; password = testpassword" ; Connection c (url); | onn = DDriverManager. getConnection |
Sybase 数据库
String url = " jdbc: sybase: Tds / / localhost: 5007 / tsdata " ; Properties sysProps = System. getProperties( ); sysProps. put( " user" ," userid" ); sysProps. put( " password" ," user_password" ); Connection conn = DDriverManager. getConnection(url,sysProps);
MySQL 数据库
String url = " jdbc:mysql: / / localhost:3306 / testDB? user = root&password = &useUnicode =
true &characterEncoding = gb2312" ; Connection conn = DriverManager. getConnection(url);
PostgreSQL 数据库
String url = " jdbc:postgresql: / / localhost / testDB" ; String user = " myuser" ; String password
= " mypassword" ; Connection conn = DriverManager. getConnection(url,user,password);
Access 数据库
Connection dbConn = DriverManager. getConnection ( " jdbc: odbc: test" ) / / test 数 据 源
名称
(4) 建立 Statement 对象或 PreparedStatement 对象。
建立 Statement 对象
Statement stmt = conn. creatStatement( );
PreparedStatement 对象
String sql = " select ∗ from users where userName = ? and password = ?" ; PreparedStatement
pstmt = conn. prepareStatement(sql); pstmt. setString(admin); pstmt. setString(liubin);
(5) 执行 SQL 语句:
执行静态 SQL 查询
String sql = " select ∗ from users" ; ResultSet rs = stmt. executeQuery (sql);
执行动态 SQL 查询
ResultSet rs = pstmt. executeQuery ( );
执行 insert, update, delete 等语句, 先定义 sql stmt. executeUpdate (sql);
(6) 访问结果记录集 ResultSet 对象:
While (re. next ( )) { out. println ( " 你的第一个字段内容为:" + rs. getString (1))
out. println (" 你的第二个字段内容为:" + rs. getString (2)); }
(7) 依次将 ResultSet, Statement, PreparedStatement, Connection 对象关闭, 释放所占用
的资源, 如 rs. close ( ); stmt. close ( ); pstmt. close ( ); con. close ( )。
7. 3. 2 使用 Statement 执行 SQL 语句
java. sql 包下有两个非常重要的接口———Statement 与 ResultSet。 Statement 定义运行
SQL 指令所需的方法成员, 如果运行的 SQL 是一种 Select 类型的指令, ResultSet 将封装
Statement 运行 SQL 指令后所返回的数据内容, 用户通过 ResultSet 取得 SQL 返回的数据
内容。
JSP 网页在使用 Statement 的功能之前, 必须先取得其对象, 而 Statement 类型的对象
则是通过引用 Connection 接口类型对象的方法成员 createStatement ( ) 所产生的。图 7-16 给出了 Statement 与 ResultSet 类型对象, 说明了它们在整个 JSP 网页当中所扮演的角色。
JSP 网页通过 SQL 的引用, 可以进行各种数据库的操作, 其中包含了修改数据库结构和数据内容的更新和查询。 修改数据库结构包含了新增与删除数据表、 变更数据表内容、 修改字段等; 数据查询与更新则是根据条件从数据库中取出部分数据, 或是新增、 删除、 修改数据内容。
Statement 主要提供运行 SQL 指令的方法, 以及设置 SQL 后返回 ResultSet 类型对象的属性, 见表 7-3。
1. exeuteQuery ( ) 方法
exeuteQuery ( ) 方法用于执行产生单个结果集的 SQL 语句, 如 Slect 语句。 exeuteQuery
( ) 方法在 Statement 接口中的完整声明如下:
ResultSet executeQuery (String sql) throws SQLException
【例 7-2 】 下面的 testExecuteQuery. jsp 中使用 executeQuery ( String sql) 方法访问
student 中的数据, 并显示返回的结果, 如图 7-17 所示。
testExecuteQuery. jsp 的代码如下:
< % @ page contentType = " text / html; charset = gb2312" language = " java" errorPage = " " % >
< % @ page import = " java. sql. ∗ " % >
< ! DOCTYPE HTML PUBLIC " - / / W3C / / DTD HTML 4. 01 Transitional / / EN" >
< html >
< head >
< meta http - equiv = " Content - Type" content = " text / html; charset = gb2312" >
< title > testexecuteQuery < / title >
< / head >
< body >
< %
String url = " jdbc:mysql: / / localhost / ch10" ;
String userName = " root" ;
String password = " root" ;
String sql = null;
Connection conn = null;
Statement stmt = null;
try {
Class. forName(" com. mysql. jdbc. Driver" );
} catch(ClassNotFoundException e) {
out. println("加载驱动器类时出现异常" );
} tr
y {
conn = DriverManager. getConnection(url, userName, password);
/ / 创建 Statement 语句
stmt = conn. createStatement( );
sql = " SELECT ∗ FROM student" ;
/ / 使用 executeQuery 执行 SQL 查询语句
ResultSet rs = stmt. executeQuery(sql);
% >
< table width = "740" border = "1" cellspacing = "0" cellpadding = "6" >
< tr >
< td width = "120" align = " center" valign = " middle" > 编号 < / td >
< td width = "145" align = " center" > 姓名 < / td >
< td width = "253" align = " center" > 地址 < / td >
< td width = "148" align = " center" > 出生日期 < / td >
< / tr >
< %
/ / 显示返回的结果集
while (rs. next( )) {
int id = rs. getInt(1);
String name = rs. getString(2);
String address = rs. getString(3);
String birthday = rs. getString(4);
% >
< tr >
< td height = "40" align = " center" valign = " middle" > < % = id% > < / td >
< td align = " center" valign = " middle" > < % = name% > < / td >
< tdvalign = " middle" > < % = address% > < / td >
< td align = " center" valign = " middle" > < % = birthday% > < / td >
< / tr >
< % }
rs. close( );
stmt. close( );
} catch(SQLException e) {
out. println("出现 SQLException 异常" );
} finally {
/ / 关闭语句和数据库连接
try {
if (conn ! = null) conn. close( );
} catch(SQLException e) {
out. println("关闭数据库连接时出现异常" );
}
}
% >
< / body >
< / html >
2. executeUpdate ( ) 方法
executeUpdate ( ) 方法运行给定的 SQL 语句, 可以使用 INSERT、 UPDATE 或 DELETE语句; 或不返回任何内容的 SQL 语句, 如 CREAT TABLE 和 DROP TABLE。 INSERT、 UPDATE 或 DELETE 语句的效果是修改表中多行的一列或多列。 executeUpdate ( ) 方法的返回值是一个整数, 指示受影响的行数。 对于 CREAT TABLE 和 DROP TABLE 等不操作行的语句, executeUpdate ( ) 的返回值总是零。
executeUpdate( )方法在 Statement 接口中的声明如下:
intexecuteUpdate(String sql) throws SQLException; / / 同时抛出 SQL 异常
【例 7-3】 下面的 testExecuteUpdate. jsp 中使用 executeUpdate ( ) 方法访问 student 中的
数据, 并显示返回的结果, 如图 7-18 所示。
testExecuteUpdate. jsp 的代码如下:
< % @ pagecontentType = " text / html; charset = gb2312" language = " java" errorPage = " " % >
< % @ page import = " java. sql. ∗ " % >
< ! DOCTYPE HTML PUBLIC " - / / W3C / / DTD HTML 4. 01 Transitional / / EN" >
< html >
< head >
< meta http - equiv = " Content - Type" content = " text / html; charset = gb2312" >
< title > testexecuteUpdate < / title >
< / head >
< body >
< % String url = " jdbc:mysql: / / localhost / ch10" ;
String userName = " root" ;
String password = " root" ;
Stringsql = null;
Connection conn = null;
Statement stmt = null;
try {
Class. forName(" com. mysql. jdbc. Driver" );
} catch(ClassNotFoundException e) {
out. println("加载驱动器类时出现异常" );
} tr
y {
conn = DriverManager. getConnection(url, userName, password);
/ / 创建 Statement 语句
stmt = conn. createStatement( );
sql = " DELETE FROM student WHERE stu_id = 10" ;
/ / 使用 executeUpdate 执行更新语句
intaffectedRowCount = stmt. executeUpdate(sql);
out. println("删除操作影响的数据行数为:" + affectedRowCount + " < br > " );
/ / 使用 executeUpdate 执行更新语句
sql = " INSERT INTO student(name,address,birthday)" +
" VALUES( 小王 , 北京 , 1980 - 05 - 10 )" ;
affectedRowCount = stmt. executeUpdate(sql);
out. println("插入操作影响的数据行数为:" + affectedRowCount + " < br > " );
sql = " update student set address = 'shanghai' where stu_id = 11 " ;
affectedRowCount = stmt. executeUpdate(sql);
out. println("修改操作影响的数据行数为:" + affectedRowCount + " < br > " );
stmt. close( );
} catch(SQLException e) {
out. println("出现 SQLException 异常" );
} finally {
/ / 关闭语句和数据库连接
try {
if (conn ! = null) conn. close( );
} catch(SQLException e) {
out. println("关闭数据库连接时出现异常" );
}
} %
>
< / body >
< / html >
3. execute ( ) 方法
execute ( ) 方法用于执行返回多个结果集、 多个更新计数或两者组合的语句。 execute
( ) 方法应该仅在语句能返回多个 ResultSet 对象、 多个更新计数或 ResultSet 对象与更新计
数的组合时使用。 当执行某个已存储过程或动态执行未知 SQL 字符串时, 有可能出现多个结果的情况, 尽管这种情况很少见。 execute ( ) 方法可以执行查询语句也可执行修改语句。
execute( )方法在 Statement 接口中的声明如下:
boolean execute(String sql) throws SQLException; / / 同时抛出 SQL 异常
【例 7-4】 下面的 testExecute. jsp 中使用 execute ( ) 方法访问 student 中的数据, 并显
示返回的结果, 如图 7-19 和图 7-20 所示。
testExecute. jsp 的代码如下:
< % @ pagecontentType = " text / html; charset = gb2312" language = " java" errorPage = " " % >
< % @ page import = " java. sql. ∗ " % >
< ! DOCTYPE HTML PUBLIC " - / / W3C / / DTD HTML 4. 01 Transitional / / EN" >
< html >
< head >
< meta http - equiv = " Content - Type" content = " text / html; charset = gb2312" >
< title > test execute < / title >
< / head >
< body >
< % Stringsql = request. getParameter(" sqltest" );
if(sql = = null){% >
< form name = " Example" method = " post" action = " " >
< p > sql 语句: < input type = " text" name = " sqltest" size = "100" maxlength = "100" > < / p >
< p > < input type = " submit" value = "传送" > < / p >
< % }else{
String url = " jdbc:mysql: / / localhost / ch10" ;
String userName = " root" ;
String password = " root" ;
Connection conn = null;
Statement stmt = null;
try {
Class. forName(" com. mysql. jdbc. Driver" );
} catch(ClassNotFoundException e) {
out. println("加载驱动器类时出现异常" + " < br > " );
}
try {
conn = DriverManager. getConnection(url, userName, password);
/ / 创建 Statement 语句
stmt = conn. createStatement( );
out. println("执行的 SQL 语句为:" + sql + " < br > " );
/ / 使用 execute 执行未知 SQL 语句
booleanisResultSet = stmt. execute(sql);
int count = 0;
while (true) {
count + + ;
if (isResultSet) {
ResultSet rs = stmt. getResultSet( );
out. println("返回的执行结果 " + count + " 为结果集" + " < br > " );
/ / 显示返回的结果集
while (rs. next( )) {
int f1 = rs. getInt(1);
String f2 = rs. getString(2);
String f3 = rs. getString(3);
out. println(f1 + " " + f2 + " " + f3);
out. println(" < br > " );
} r
s. close( );
} e
lse {
int affectedRowCount = stmt. getUpdateCount( );
if (affectedRowCount = = - 1) break;
out. println("返回的执行结果 " + count + " 为更新计数" + " < br > " );
out. println("更新计数为:" + affectedRowCount + " < br > " );
} i
sResultSet = stmt. getMoreResults( );
} s
tmt. close( );
} catch(SQLException e) {
out. println("出现 SQLException 异常" );
} finally {
/ / 关闭语句和数据库连接
try {
if (conn ! = null) conn. close( );
} catch(SQLException e) {
out. println("关闭数据库连接时出现异常" );
}
} }% >
< / form >
< / body >
< / html >