59

第 12 章 JDBC 数据库应用程序设计

  • Upload
    tasya

  • View
    190

  • Download
    0

Embed Size (px)

DESCRIPTION

第 12 章 JDBC 数据库应用程序设计. 12.1 JDBC 概述. JDBC(Java Data Base Connectivity ,其中文含义是 Java 数据库连接 ) ,可以将它理解为一种数据库存取的综合技术。 JDBC 内嵌于 Java 中, 提供存取关系数据库的标准库。其主要由两部分组成: JDBC API 和 JDBC 驱动程序管理器。所有用户界面的生成,事件驱动,对数据库的存取等功能均是由 Java 来实现的。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第 12 章  JDBC 数据库应用程序设计
Page 2: 第 12 章  JDBC 数据库应用程序设计

12.1 JDBC概述 JDBC(Java Data Base Connectivity ,其中文含义是

Java 数据库连接 ) ,可以将它理解为一种数据库存取的综合技术。

JDBC 内嵌于 Java 中, 提供存取关系数据库的标准库。其主要由两部分组成: JDBC API 和 JDBC 驱动程序管理器。所有用户界面的生成,事件驱动,对数据库的存取等功能均是由 Java 来实现的。

因为数据库应用的重要性,在 JDK 6 中集成了 Java 数据库系统 Java DB , JDBC API 也进行了升级,使得数据库的访问更加方便和有效。

Page 3: 第 12 章  JDBC 数据库应用程序设计

1. 数据库概述 数据库是指长期存储在计算机内,有组织、可共享

的数据集合。有大量的数据库产品可应用于实际的数据库管理和程序设计。例如, Oracle , SQL Server , DB2 , SyBase , FoxPro , Access ,MySQL 等。其中大量应用的数据库产品是关系型数据库系统,关系数据库有严格的数学理论为基础,数据和数据之间的联系表示为二维表的形式 ( 关系 ) ,用户使用直观、简单。

Page 4: 第 12 章  JDBC 数据库应用程序设计

考号 姓名 性别 出生日期 数学 语文 英语 综合420102500

1王丹 女 1989-10-

1595 87 88 78

4201025002

李屹 男 1988-12-26

96 80 88 85

4201025003

赵星 男 1989-5-3 90 75 84 82

4201025004

黄萍 女 1989-3-12 88 79 90 80

通常按照习惯,将二维表的行称为记录,列称为字段或域。一个数据库由若干表 ( 即关系 ) 构成,其中一些表可表示数据,另一些表可表示数据之间的联系。例如 : 设在“学生”数据库中有“学生成绩”表,其内容如表 12-1 所示: 表 12-1“ 学生成绩”数据表

Page 5: 第 12 章  JDBC 数据库应用程序设计

2.JDBC 连接数据库的方式 在 Java 程序中要对数据库进行各种操作,可使用

JDBC 技术实现对数据库的连接和访问。本书主要介绍JDBC 连接数据库的两种方式:使用 JDBC - ODBC桥接器和直接使用某种数据库的驱动程序。

(1) 使用 JDBC - ODBC Bridge( 桥接器 ) 此种方式利用微软公司定义的 ODBC( 开放数据库连

接 ) 对数据库访问的通用接口来访问操作数据库。因为ODBC 支持大多数数据库的连接和访问, JDBC 通过JDBC - ODBC 桥来将 JDBC API 转换成 ODBC API ,进而通过 ODBC 来存取数据库。

Page 6: 第 12 章  JDBC 数据库应用程序设计

为 了 使 用 这 种 方 式 连 接 和 访 问 数 据 库 , 需 在Windows 系统中创建与数据库对应的数据源。

在 Windows XP 中,可在控制面板中选择“管理工具”,在其中的项目中选择“数据源( ODBC )”,可设置 SQL Server 2000

数据库中的数据库 “ 学生”(在 SQL Server 中已经建立) 为 ODBC 数据源。 名称为 student 的数 据源设置完成后的 情况见图。

Page 7: 第 12 章  JDBC 数据库应用程序设计

(2) 使用某种数据库的专用驱动程序 此种方式是 JDBC 与某种数据库的专用驱动程序相

连,不用创建数据源就能存取相应的数据库。如对SQL Server ,可以到下面的网页去下载“ SQL Server Driver for JDBC” :http://www.microsoft.com/china/sql/downloads/

download.mspx 下载后得到一个 3MB 多的

sqljdbc_3.0.1301.101_chs.exe 文件,这是SQL Server 2000 、 2005 和 2008 都能使用的较新的 JDBC 驱动程序,运行该文件可进行驱动的安装。在安装目的文件夹中可以找到sqljdbc.jar 和 sqljdbc4.jar 文件,按照说明书的要求,由于所用的是 JDK 版本 6 ,因此这里应使用 sqljdbc4.jar ,可将它设置到 classpath类搜索路径中。

Page 8: 第 12 章  JDBC 数据库应用程序设计

若是用 JDK 命令行方式进行 Java 程序的编译和运行,可在“我的电脑”的属性对话框(右单击“我的电脑”出现该对话框)中的“高级”选项卡中选择“环境变量”按钮后出现的“环境变量”对话框中的系统变量部分对 classpath参数进行设置, classpath 的值应为:

{ 安装文件夹 }\sqljdbc_3.0\chs\sqljdbc4.jar 若是用 JCreator 开发工具进行程序设计,则可选择

JCreator 的 configure菜单的 Options菜单项,在左边的列表中选择 JDK Profile并选中右边的列表项后,选择 Edit 按钮,在出现的 JDK Profile 对话框,点击“ Add” 按钮,并选择 add archive 项,再在“打开”对话框中选择 sqljdbc4.jar 文件来进行 classpath的设置。使用专用驱动程序的方式,不需要做更多的设置,但是, SQL Server 2000 需要安装 SP4补丁才能使用。另外,需注意的是,使用 sqljdbc4.jar 新驱动程序,在程序中代码部分写法与早期的驱动写法有所不同。

Page 9: 第 12 章  JDBC 数据库应用程序设计

3.JDBC 连接数据库程序设计的主要步骤 应用 JDBC 设计数据库应用程序,需要使用到较多

的 Java 类与接口,掌握这些类与接口,并遵从一定的操作步骤,就能顺利进行数据库的存取,从而进行数据库应用程序的设计。 JDBC 的类和方法都包含在 java.sql包中, Java 数据库应用程序的设计都需要引入 java.sql包。下面从基本应用的角度,按照数据库应用程序的设计步骤来介绍 JDBC 相关类和接口。

(1) 装载驱动程序首先使用 Class 类的 forName 方法来装载驱动程

序。装载驱动程序要处理异常。两种装载驱动程序的方法如下:

Page 10: 第 12 章  JDBC 数据库应用程序设计

使用 ODBC - JDBC 桥接器的例:try {

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

}catch(java.lang.ClassNotFoundException e) { System.out.println(" 类未找到错误! "+e);}

使用 SQL Server 2000 驱动程序的例:try {

Class.forName("com.microsoft.jdbc.sqlserver .SQLServerDriver");}catch(java.lang.ClassNotFoundException e) {

System.out.println(" 类未找到错误! "+e);}

Page 11: 第 12 章  JDBC 数据库应用程序设计

(2) 定义连接 URL 指定装载的数据库驱动程序后,可用 DriverManager

类来进行数据源或数据库的连接。 DriverManager 类是 JDBC 基础 ,用来管理 JDBC 驱动程序。该类有静态的getConnection() 方法 ,用于验证 JDBC 数据源 , 并返回接口 Connection 对象。

使用 ODBC - JDBC 桥接器的例:Connection con = DriverManager.getConnection

("jdbc:odbc:student","sa","123456"); 其中的 "student"为建立的数据源的名

称, "sa"和 "123456"为安装 SQL Server 2000 数据库系统时设置的用户名和访问密码(这里可根据实际用户名和密码来进行设置)。

Page 12: 第 12 章  JDBC 数据库应用程序设计

使用 SQL Server 2000 驱动程序方式的例:Connection con = DriverManager.getConnection

("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName= 学生 ","sa","123456");

其中的 "localhost "表示使用本地服务器(可根据实际名称填写), "1433"为访问 SQL 数据库的服务器默认端口号, "学生 "为 SQL Server 2000 数据库文件名, "sa"和 "123456"的意义为安装 SQL Server 2000时设置的用户名和密码(可根据实际情况来填写)。

(3) 获取数据库信息和创建接口 Statement 对象 数据库连接成功后,可以使用 Connection 对象的

getMetaData 方法取得接口 DatabaseMetaData(提供大量的方法)对象来了解数据源或数据库的各种信息。

Page 13: 第 12 章  JDBC 数据库应用程序设计

例如: DatabaseMetaData dbmd = con.getMetaData(); // 返回DatabaseMetaData 对象 dbmd.getURL() // 获得数据库的 URL dbmd.getUserName() // 获得用户名 dbmd.getDriverName() // 获得数据库驱动程序名 dbmd.getDriverVersion() // 获得数据库驱动程序版本 dbmd.getDatabaseProductName()// 获得数据库产品名称 dbmd.getDatabaseProductVersion()//获得数据库产品版

本 dbmd.getTables()//获得数据库中数据表的信息 ( 有方法参数 ) dbmd.getColumns()//获得数据表中各列的信息 ( 有方法参数 )

Page 14: 第 12 章  JDBC 数据库应用程序设计

数据库连接成功后,还可以使用向数据库发送访问数据库的 SQL语句的方法来存取数据库。 JDBC 使用接口 Statement 的对象 ( 或执行数据库存储过程的子接口 CallableStatement 、发送带参数的SQL语句的子接口 PreparedStatement) 来发送 SQL语句, Statement 对象可用Connection 的方法 createStatement() 来返回。例如:Statement st = con.createStatement();

(4) 执行 SQL语句以存取数据库希望执行的 SQL语句串作为 Statement 的方法

execute() 等的参数向数据库传送,以交给数据库引擎,执行 SQL 对数据库的访问操作。对数据库访问结果是一个数据表的情况,可将这个表(结果集)存入接口 ResultSet 的对象。

Page 15: 第 12 章  JDBC 数据库应用程序设计

提交 SQL语句的 Statement 的方法有 execute 、executeQuery 和 executeUpdate 等,分别用于不同类型的 SQL语句的提交。

executeQuery 方法用于产生单个结果集的语句,如查询语句 select 。 executeUpdate 方法用于执行 SQL语句中不产生结果集的语句,如insert , delete , update 等语句和数据定义语句等 ( 它的返回值为本次操作影响数据库表中数据行行数的整数值或零 ) 。 execute 方法可用于执行产生多个结果集或对数据库进行多个操作的 SQL语句( 例如,执行数据库的存储过程 ) 。下面是使用executeQuery 方法和 executeUpdate 方法的例子:ResultSet rs = st.executeQuery("select * from 学生成绩 ");

int n=st.executeUpdate( "delete from 学生成绩 where 综合 <60");

Page 16: 第 12 章  JDBC 数据库应用程序设计

(5) 对执行 SQL语句的结果进行处理 Statement 对象将 SQL语句封装起来交给数据库引擎,执行 select查询语句,将得到结果集ResultSet 对象(注意:执行insert 、 delete 、 update 等查询语句无结果集)。接口 ResultSet 对象封装了执行 SQL语句的返回结果,以后可根据需要,以便在屏幕上显示结果或做进一步的处理。

在执行 select语句后的返回结果中,包含了数据表和数据表内容的相关信息。关于数据表的信息可通过ResultSet 的 getMetaData 方法来创建ResultSetMetaData 对象,由这个对象可获取所需数据库的信息。

Page 17: 第 12 章  JDBC 数据库应用程序设计

例如:ResultSetMetaData rsmd = rs.getMetaData();rsmd.getColumnCount() // 获取列(字段)数rsmd.getColumnName( 列号 ) // 获取指定列(字段)

的列名 在 ResultSet 中,提供了一整套的 getXXX 方法

(如getInt , getString , getFloat , getDouble等)来访问结果集中当前行的不同列(用列序号或列标题作为这些方法的参数)的数据(类型不同时可将字段类型按照 XXX 类型来进行类型转换),而 next 方法可使得访问可对不同的行来进行。

Page 18: 第 12 章  JDBC 数据库应用程序设计

例如,可用下面的程序段对学生成绩表的姓名和出生日期进行访问:ResultSet rs = st.executeQuery( "select 姓名 , 出生日期 from 学生成绩 ");while(rs.next()){ System.out.println(rs.getString("姓名 ") // 用字段 ( 列 ) 名 +" " + rs.getString(2).substring(0,10)); // 用字段 ( 列 ) 序号, // 而且将日期类型的字段转换为 String 类型进行显示。}

Page 19: 第 12 章  JDBC 数据库应用程序设计

ResultSet自动维护结果集当前数据行的指向光标,首先获得结果集时,指向光标置于结果集的第一行前,以后每调用一次 next 方法,光标就向下移动一行,这样可按照顺序从第一行到最后一行逐行访问结果集的每一行(访问结束时 next返回 false值)。

在有些情况下,可能希望任意访问而不是顺序访问结果集的数据行,对某些结果集,可能还希望通过结果集修改数据库的数据,则应在 createStatement 方法中加入如下的两个参数,即:Statement st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

Page 20: 第 12 章  JDBC 数据库应用程序设计

如果只希望任意滚动结果集的指向光标,而不修改数据库的数据,则可在上述两个参数中将第二个参数设置为 ResultSet.CONCUR_READ_ONLY 。

通过参数的设置,就可以用 ResultSet 的 first(定位到第一行)、 last (定位到最后一行)、 previous (定位到前一行)、 absolute(绝对行号)和 relative (相对当前行的行号)等方法来设置当前行,并且还可以根据参数的更新设置,用 insertRow (插入行)、 deleteRow(删除行)、 updateRow (更新行)等方法来对数据库表进行增、删、改的操作。

Page 21: 第 12 章  JDBC 数据库应用程序设计

(6) 关闭连接 数据库访问结束,为保证数据库数据的完整性和释

放系统资源,应明确地关闭数据库的连接:一般是关闭结果集、关闭数据库访问对象和关闭连接。

Page 22: 第 12 章  JDBC 数据库应用程序设计

12.2 JDBC数据库操作实例【例 12.1】用表 12.1 的数据在数据库“学生”中

建立数据表“学生成绩”,并显示建表以后的结果。在程序中给出的是使用直接驱动程序方式连接数据库的代码,并用注释方式给出了使用 JDBC-ODBC 桥接器方式连接数据库的代码。(使用 JDBC-ODBC桥接器方式时将该语句的注释符号去掉,并将上面有“ *”号注释的语句去除或设置为注释。)如前所述,程序中的第一个 try - catch语句部分可以省略不写,使得程序变得简单。

import java.sql.*;class JdbcDemo{public static void main(String args[]){ Connection con; // 定义连接类的对象

Page 23: 第 12 章  JDBC 数据库应用程序设计

Statement st; // 为 SQL语句的使用定义对象ResultSet rs; // 定义结果集对象String user="sa",pass="123456"; // 设置数据库的用户名和密码try {//Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Class.forName("com.microsoft.sqlserver.jdbc.SQLS

erverDriver");// *}catch(ClassNotFoundException e) { System.out.println(" 类未找到错误! " + e);}try{con=DriverManager.getConnection("jdbc:odbc:stu

dent",user,pass);con = DriverManager.getConnection ("jdbc:sqlserver://localhost:1433;DatabaseName=

学生 ",user,pass);//*

Page 24: 第 12 章  JDBC 数据库应用程序设计

DatabaseMetaData dbmd = con.getMetaData();

System.out.println(" 数据库的 URL : "+ dbmd.getURL()); System.out.println(" 数据库用户名: "+ dbmd.getUserName()); System.out.println(" 数据库驱动程序名: "+ dbmd.getDriverName()); System.out.println(" 数据库驱动程序版本号: "+ dbmd.getDriverVersion()); System.out.println(" 数据库产品名: "+ dbmd.getDatabaseProductName()); System.out.println(" 数据库产品版本号: "+ dbmd.getDatabaseProductVersion());

Page 25: 第 12 章  JDBC 数据库应用程序设计

st=con.createStatement();String query = "create table 学生成绩 ("+ "考号 char(10),姓名 char(8), 性别 char(2),出生日期 datetime," + " 数学 integer,语文 integer,英语 integer, 综合 integer)";st.executeUpdate(query);String s1="insert into 学生成绩 values("

+"'4201025001','王丹 ',' 女 ','1989-10-15', 95,87,88,78)";

String s2="insert into 学生成绩 values(" +"'4201025002','李屹 ',' 男 ','1988-12-26',

96,80,88,85)";String s3="insert into 学生成绩 values(" +"'4201025003','赵星 ',' 男 ','1989-5-3',

90,75,84,82)";

Page 26: 第 12 章  JDBC 数据库应用程序设计

String s4="insert into 学生成绩 values(" +"'4201025004','黄萍 ',' 女 ','1989-3-

12',88,79,90,80)";st.executeUpdate(s1); // 执行 SQL语句的提交st.executeUpdate(s2);st.executeUpdate(s3);st.executeUpdate(s4);rs=st.executeQuery("select * from 学生成绩 "); // 查询建表并插入数据的结果System.out.println(" [ 学生成绩 ] 表中的数据如

下: ");System.out.println(" 考号 姓名 性别 出生日期 数 语 英 综 ");

while(rs.next()) // 在输出数据间加竖线符进行分隔System.out.println(rs.getString(1)+"|"// 输出考号

+rs.getString(2)+"|" // 输出姓名 +rs.getString(3)+"|" // 输出性别

Page 27: 第 12 章  JDBC 数据库应用程序设计

+rs.getString(4).substring(0,10)+"|" // 输出出生日期 +rs.getString(5)+"|" // 输出数学成绩 +rs.getString(6)+"|" // 输出语文成绩 +rs.getString(7)+"|" // 输出英语成绩 +rs.getString(8)); // 输出综合成绩 rs.close();st.close();con.close(); }catch(java.sql.SQLException e){ System.out.println("SQL错误! " + e); } }}

Page 28: 第 12 章  JDBC 数据库应用程序设计

例 12.1 程序的运行结果如下:数据库的 URL : jdbc:sqlserver://

localhost:1433;xopenStates=false;sendTimeAsDatetime=true;trustServerCertificate=false;sendStringParametersAsUnicode=true;selectMethod=direct;responseBuffering=adaptive;packetSize=8000;loginTimeout=15;lockTimeout=-1;lastUpdateCount=true;encrypt=false;disableStatementPooling=true;databaseName= 学生 ;applicationName=Microsoft SQL Server JDBC Driver;

数据库用户名: sa数据库驱动程序名: Microsoft SQL Server JDBC Driver 3.0数据库驱动程序版本号: 3.0.1301.101数据库产品名: Microsoft SQL Server数据库产品版本号: 8.00.2039 [ 学生成绩 ] 表中的数据如下: 考号 姓名 性别 出生日期 数 语 英 综4201025001|王丹 | 女 |1989-10-15|95|87|88|784201025002|李屹 | 男 |1988-12-26|96|80|88|854201025003|赵星 | 男 |1989-05-03|90|75|84|824201025004|黄萍 | 女 |1989-03-12|88|79|90|80

Page 29: 第 12 章  JDBC 数据库应用程序设计

【例 12.2】设计一个 Java 数据库应用程序,它能按照菜单(用输出对话框显示)的选项,对例 12.1创建的学生成绩表进行任意的记录显示、人机对话方式添加记录(用输入对话框来输入添加的学生记录数据),根据输入的学生考号来删除学生数据记录。import javax.swing.JOptionPane;import java.sql.*;class JdbcDemo1{ public static void main(String args[]){ Connection con; Statement st; ResultSet rs; String user="sa",pass="123456",s,s1,s2,ss;

Page 30: 第 12 章  JDBC 数据库应用程序设计

try {//

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");// * 驱动程序名

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

}catch(ClassNotFoundException e) { System.out.println(" 类未找到错误! " + e);}try {

//con=DriverManager.getConnection("jdbc:odbc:student",user,pass);

con = DriverManager.getConnection ("jdbc:sqlserver://localhost:1433;

DatabaseName = stu",user,pass);

Page 31: 第 12 章  JDBC 数据库应用程序设计

while(true){ s=JOptionPane.showInputDialog( "请选择: \n 1.显示记录 \n 2.添加记录 \n 3.删除记录 \n 4.退出 "); st=con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); // 设置数据库指针可任意移动 rs=st.executeQuery("select * from 学生成

绩 "); if(s.equals("1")){ s1 = JOptionPane.showInputDialog( "请输入 [ 开始记录号 (>=1) ,记录数 ]"); String sa[]=s1.split(","); listRecord(rs,Integer.parseInt(sa[0]), Integer.parseInt(sa[1]));

Page 32: 第 12 章  JDBC 数据库应用程序设计

// 调用 listRecord显示记录,参数为结果集,开始记录号,显示记录数

}else if(s.equals("2")){s1 =JOptionPane.showInputDialog(

"请输入 [ 考号 , 姓名 ,性别 , 出生日期 ,数学 , 语文 , 英语 ,综

合 ]"); String a[]=s1.split(","); ss="insert into 学生成绩 values('"+a[0]+"','"+a[1]+"','"+a[2]; ss+="','"+a[3]+"',"+a[4]+","+a[5]+","+ a[6]+","+a[7]+")";

Page 33: 第 12 章  JDBC 数据库应用程序设计

JOptionPane.showMessageDialog(null, "添加记录的 SQL语句是: \n"+ss); st.executeUpdate(ss);}else if(s.equals("3")){ s1 =JOptionPane.showInputDialog( "请输入要删除记录的学生考号: "); PreparedStatement ps =

con.prepareStatement( "delete from 学生成绩 where 考号=?"); // 带参数的 SQL语句 ps.setString(1,s1);// 设置参数实际值, 1 为参数序号 ps.executeUpdate();}else {

Page 34: 第 12 章  JDBC 数据库应用程序设计

rs.close(); st.close(); con.close(); System.exit(0); } } }catch(java.sql.SQLException e){ System.out.println("SQL错误! " + e); }}// 下面为显示记录的 listRecord 方法,忽略异常的处理static void listRecord(ResultSet rs,int start,int

n)throws SQLException{ int i=1; String ss=""; rs.absolute(start);

Page 35: 第 12 章  JDBC 数据库应用程序设计

while(i<=n){ ss+=rs.getString(1)+"|"; // 输出考号 ss+=rs.getString(2)+"|"; // 输出姓名 ss+=rs.getString(3)+"|"; // 输出性别 ss+=rs.getString(4).substring(0,10)+"|"; // 输出出生日期 ss+=rs.getString(5)+"|"; // 输出数学成绩 ss+=rs.getString(6)+"|"; // 输出语文成绩 ss+=rs.getString(7)+"|"; // 输出英语成绩 ss+=rs.getString(8); // 输出综合成绩 ss+="\n"; i++; if(!rs.next())break; } JOptionPane.showMessageDialog(null, "显示记录如下: \n"+ss); }}

Page 36: 第 12 章  JDBC 数据库应用程序设计

【例 12.3】设计一个 Java 数据库 GUI 应用程序,它能根据提示在一个文本区中输入查询数据库的SQL语句,按“显示” 按钮后在下面的一个表格中显示查询结果。import java.awt.*;import java.awt.event.*;import java.sql.*;import javax.swing.*;import javax.swing.table.*;class RSTable extends AbstractTableModel { private Connection con; private Statement st; private ResultSet rs; private ResultSetMetaData rsmd; private int numberOfRows;

Page 37: 第 12 章  JDBC 数据库应用程序设计

private String user="sa",pass="123456", qs = "SELECT * FROM 学生成绩 "; public RSTable(String query) throws

SQLException, ClassNotFoundException{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection( "jdbc:odbc:student",user,pass); st = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY ); // 设置结果集为可滚动并且是只读的 setQuery(query);}public Class getColumnClass(int column){ try { // 获得结果集列的类名

Page 38: 第 12 章  JDBC 数据库应用程序设计

String className =rsmd.getColumnClassName(column+1);

return Class.forName( className ); }catch ( Exception e ) { System.out.println(e); } return Object.class;}public int getColumnCount(){ try { return rsmd.getColumnCount();// 获得结果集的列

数 }catch ( SQLException se ){ System.out.println(se); } return 0; // 出错时返回 0 列}

Page 39: 第 12 章  JDBC 数据库应用程序设计

public String getColumnName( int column ){ try { return rsmd.getColumnName( column + 1 ); // 获得结果集的列名 }catch ( SQLException se ) { System.out.println(se); } return ""; // 出错时返回空字符串}public int getRowCount(){ return numberOfRows; // 获得结果集的行数} // 获得结果集指定行列处的数据

Page 40: 第 12 章  JDBC 数据库应用程序设计

public Object getValueAt( int row, int column ){ try { rs.absolute( row + 1 ); return rs.getObject( column + 1 ); }catch (SQLException se) { System.out.println(se); } return "";}protected void finalize(){ // 在对象撤销时自动调用来关闭数据库连接等 try { rs.close(); st.close(); con.close(); }catch ( SQLException se ){ System.out.println(se); }}public void setQuery( String query ) throws SQLException{

Page 41: 第 12 章  JDBC 数据库应用程序设计

rs=st.executeQuery(query);//执行查询,返回结果集

rsmd = rs.getMetaData(); // 获得结果集的元数据 rs.last(); // 移动数据表指针到最后一行 numberOfRows = rs.getRow();// 获得最后一行的

行号 fireTableStructureChanged();// 更新查询显示 }}

Page 42: 第 12 章  JDBC 数据库应用程序设计

public class JdbcDemo2 extends JFrame implements ActionListener{

private RSTable table; private JTextArea jta; public JdbcDemo2(){ super( "JdbcGUI 应用程序:显示数据库查询结果 " ); // 设置窗口标题 String qs = "select * from 学生成绩 "; // 设置初始显示的 SQL语句 try { table = new RSTable(qs ); // 创建 RSTable 对象

jta = new JTextArea( qs, 2, 120 );// 设置文本区 jta.setWrapStyleWord( true ); // 设置换行属性

Page 43: 第 12 章  JDBC 数据库应用程序设计

jta.setLineWrap( true ); // 设置文本区换行属性jta.setFont(new Font("宋体 ",Font.PLAIN,13));// 设置字体JScrollPane scrollPane = new JScrollPane(jta,

ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,

ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );

// 设置滚动面板JLabel jl= new JLabel( "<Html><Font color=red>输入 SQL语句: ");JButton jb = new JButton( "<Html><Font color=blue>查询 ");JPanel jp=new JPanel(); // 创建面板对象jp.setLayout(new BorderLayout()); // 设置面板的布局为 BorderLayoutjp.add(jl,BorderLayout.WEST); // 添加到面板

Page 44: 第 12 章  JDBC 数据库应用程序设计

jp.add(scrollPane,BorderLayout.CENTER); // 添加到面板jp.add(jb,BorderLayout.EAST); // 添加到面板JTable resultTable = new JTable(table);resultTable.getTableHeader().setBackground(Col

or.blue); // 设置表格标题背景色为蓝色resultTable.getTableHeader().setForeground(Col

or.orange); // 设置表格标题前景色为橙色add( jp, BorderLayout.NORTH ); // 添加面板到窗体add( new JScrollPane(resultTable), BorderLayout.CENTER ); // 添加表格到窗体

Page 45: 第 12 章  JDBC 数据库应用程序设计

jb.addActionListener(this); // 注册动作监听器 }catch ( ClassNotFoundException e) { JOptionPane.showMessageDialog( null, "数据库驱动程序未找到! "," 驱动程序未找到 ", JOptionPane.ERROR_MESSAGE ); System.exit(1); // 终止应用程序 }catch (SQLException e) { JOptionPane.showMessageDialog( null, " 数据库错误! ",

"数据库错误 ",JOptionPane.ERROR_MESSAGE ); System.exit(1); // 终止应用程序 }}public void actionPerformed( ActionEvent e ){ try { table.setQuery(jta.getText()); // 将输入在文本区中 SQL语句作查询

Page 46: 第 12 章  JDBC 数据库应用程序设计

}catch (SQLException se) {//显示出错信息 JOptionPane.showMessageDialog( null, se.toString(), "数据库错误 ",JOptionPane.ERROR_MESSAGE ); } } public static void main(String args[]){ JdbcDemo2 app = new JdbcDemo2();

app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

app.setSize( 680, 250 ); // 设置初始窗口大小 app.setVisible( true ); }}

Page 47: 第 12 章  JDBC 数据库应用程序设计

例 12.3 的运行界面如下:

Page 48: 第 12 章  JDBC 数据库应用程序设计

12.3 使用 JDK内置的 Java DB

在 JDK 6 中,内置了数据库系统 Java DB ,在安装 JDK时,默认将 Java DB 安装到安装目标盘的Program Files 文件夹的 Sun 文件夹中。这是一个纯 Java 实现、开源的数据库管理系统,源于 Apache 软件基金会( ASF )名下的项目 Derby 。它只有几兆大小,但功能齐备,支持几乎大部分的数据库应用所需要的特性,这就为 JDK 注入了一股全新的活力: Java 程序员不再需要耗费大量精力安装和配置数据库,就能进行安全、易用、标准、并且免费的数据库编程。

Page 49: 第 12 章  JDBC 数据库应用程序设计

JavaDB 有两种运行模式:内嵌模式和网络服务器模式,内嵌模式中 JavaDB 和应用程序一起在同一个 Java 虚拟机( JVM )里运行。网络服务器模式中 JavaDB 和应用程序可以在不同的 JVM 中运行。

在运行实例前,需要将 JavaDB 的驱动 jar包设置到类搜索路径中。

1. JavaDB 内嵌模式用法【例 12.4】本例是 JavaDB 内嵌模式的简单应用,

在程序中建立数据库 stuDB 和建“成绩”表,插入两条记录并显示,最后删除创建的表。本程序需要重点关注的是连接 JavaDB 和创建数据库的语句,它们的格式与前面不同。

Page 50: 第 12 章  JDBC 数据库应用程序设计

import java.sql.*;public class JavaDBEmbedded {     public static void main(String[] args) {         try { // 注册并装载驱动程序,在 JDK 6 中下一语句可省,不影响程序运行

Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();

             System.out.println(" 装载内嵌驱动程序! ");             Connection conn = null;            

conn=DriverManager.getConnection("jdbc:derby:stuDB;create=true");

             System.out.println(" 创建并连接到数据库stuDB ! ");

             conn.setAutoCommit(false); // 不自动提交 // 创建成绩表并向该表插入两条记录

Page 51: 第 12 章  JDBC 数据库应用程序设计

Statement s = conn.createStatement();             s.execute("create table 成绩 (name

varchar(40), score int)");             System.out.println(" 建成绩表 !");             s.execute("insert into 成绩 values('张

三 ', 86)");             s.execute("insert into 成绩 values ('李

四 ', 92)");             // 查询成绩表中的记录 ResultSet rs = s.executeQuery(                 "SELECT name, score FROM 成绩

ORDER BY score");             System.out.println("姓名 \t 成绩 ");

Page 52: 第 12 章  JDBC 数据库应用程序设计

while(rs.next()) {                 StringBuffer builder = new

StringBuffer(rs.getString(1));           builder.append("\t");                 builder.append(rs.getInt(2));                 System.out.println(builder);             }             // 删除该表 s.execute("drop table 成绩 ");             System.out.println("删除成绩表! ");             rs.close();             s.close();

Page 53: 第 12 章  JDBC 数据库应用程序设计

System.out.println(" 关闭结果集和语句对象! ");             conn.commit();             conn.close();             System.out.println(" 提交事务,关闭连

接! ");try {                

DriverManager.getConnection("jdbc:derby:;shutdown=true");

// 连接关闭} catch (SQLException se) {

Page 54: 第 12 章  JDBC 数据库应用程序设计

if (( (se.getErrorCode() == 50000)&& ("XJ015".equals(se.getSQLState()) ))) {System.out.println("Derby正常关闭! ");} else {System.err.println("Derby非正常关闭! ");System.out.println(se);}}         } catch (Throwable e) {}     }}

Page 55: 第 12 章  JDBC 数据库应用程序设计

程序运行结果如下:装载内嵌驱动程序!创建并连接到数据库 stuDB!建成绩表 !姓名 成绩张三 86李四 92删除成绩表!关闭结果集和语句对象!提交事务,关闭连接!Derby正常关闭!

Page 56: 第 12 章  JDBC 数据库应用程序设计

2. JavaDB 网络服务器模式用法 在这种模式下,需要建立服务器进程和客户机进程,服务器进程在客户机进程启动之前先启动。为简单起见,这里说明将上面的例 12.4 应用于网络服务器模式的方法。

可以先通过点击执行 C:\Program Files\Sun\JavaDB\bin\startNetworkServer.bat 来启动网络服务器。在 JCreator 中装入客户机程序,并设置derbyclient.jar包的类搜索路径,再主要的是对例12.4 程序中的驱动装载和连接语句这两个关键语句作出修改,以应用网络服务器模式。 即

Page 57: 第 12 章  JDBC 数据库应用程序设计

forName() 部分修改为:forName("org.apache.derby.jdbc.ClientDriver

"); getConnection() 部分修改为:

getConnection("jdbc:derby://localhost:1527/stuDB;create=true");

程序中的提示信息根据实际情况作出合适的修改即可。为节省篇幅,下面仅列出相关代码部分的完整语句,其他部分与例 12.4 一致。 ……

Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();

System.out.println(" 装载客户机驱动程序! ");

Page 58: 第 12 章  JDBC 数据库应用程序设计

Connection conn = null;conn=DriverManager.getConnection("jdbc:derby://localhost:1527/

stuDB;create=true");……

为了更好的应用 JavaDB ,关于 JavaDB 的更多的信息,可以参看安装到系统的 JavaDB 中 demo 文件夹中的例子和 docs 文件夹中的文档,从互联网上也可以找到很多关于 JavaDB 和 Derby 方面的知识。

Page 59: 第 12 章  JDBC 数据库应用程序设计