580 likes | 802 Views
第 11 章 JDBC 编程. (时间: 2 次课, 4 学时). 第 11 章 JDBC 编程. 教学提示: JDBC 是一种用于执行 SQL 语句的 Java API ,是一组用 Java 编写的类和接口。它为 Java 应用提供了一种与各种不同数据库进行对话的方式。使用 JDBC 可以很容易地把 SQL 语句传送到任何关系型数据库中。 本章主要介绍: JDBC 简介、 JDBC 基本编程和 JDBC 编程实例. 第 11 章 JDBC 编程. 11.1 JDBC 简介 11.2 JDBC 基本编程 11.3 JDBC 编程实例
E N D
第11章 JDBC编程 (时间:2次课,4学时)
第11章 JDBC编程 • 教学提示:JDBC是一种用于执行SQL语句的Java API,是一组用Java编写的类和接口。它为Java应用提供了一种与各种不同数据库进行对话的方式。使用JDBC 可以很容易地把SQL 语句传送到任何关系型数据库中。 • 本章主要介绍: JDBC简介、JDBC基本编程和JDBC编程实例
第11章 JDBC编程 • 11.1 JDBC简介 • 11.2 JDBC基本编程 • 11.3 JDBC编程实例 • 11.4 课后练习
11.1 JDBC简介 • 11.1.1 从ODBC到JDBC • 11.1.2 JDBC的特点 • 11.1.3 JDBC驱动程序 • 11.1.4 JDBC API
11.1 JDBC简介 • JDBC为访问不同的数据库提供了一种统一的途径,像ODBC(Open Database Connectivity)一样,JDBC对开发者屏蔽了一些细节问题。 • JDBC的目标是使应用程序开发人员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,使得开发人员能够用纯Java API 来编写具有平台无关性的数据库应用程序,增强了数据库访问能力,大大简化和加快了开发过程。
11.1.1 从ODBC到JDBC • 基于C 语言的开放数据库互连(ODBC)是为了实现异构数据库互连而由Microsoft 公司推出的一种标准,它是一个单一的、公共的编程接口。ODBC 提供不同的程序以存取不同的数据库,但只提供一种应用编程接口(API)给应用程序,如图11-1 所示。
11.1.1 从ODBC到JDBC • 图11-1 JDBC的结构体系
11.1.1 从ODBC到JDBC • ODBC 的体系结构含有4个层次。 • (1) 应用程序(Application):执行ODBC函数的调用和处理,提交SQL语句并检索结果。 • (2) 驱动程序管理器(Driver Manager):为应用程序装载驱动程序。 • (3) 驱动程序(Driver):驱动程序是实现ODBC函数调用和同数据源交互作用的动态链接库,它执行ODBC函数调用,提交SQL请求到指定的数据源,并把结果返回给应用程序。如果需要,驱动程序也可改变应用程序的请求,以与特定的DBMS的语法匹配。 • (4) 数据源(Data Source):由用户需要存取的数据和与之相连的操作系统、DBMS及存取DBMS的网络平台组成。
11.1.2 JDBC的特点 • 与ODBC 相比,JDBC 直接在应用程序中加载驱动程序并连接特定的数据库。JDBC的体系结构如图11-2所示。在体系结构中,JDBC API 屏蔽不同的数据库驱动程序之间的差别,为开发者提供一个标准的、纯Java的数据库程序设计接口,为在Java中访问不同类型的数据库提供技术支持。驱动程序管理器(Driver Manager)为应用程序装载数据库驱动程序(JDBC Driver),数据库驱动程序是与具体的数据库相关的,由数据库开发商提供,用于向数据库提交SQL 请求,完成对数据库的访问。
11.1.2 JDBC的特点 • 图11-2 JDBC的体系
11.1.2 JDBC的特点 • 与ODBC 相类似,JDBC 接口(API)包含两层。 • (1) JDBC API:抽象接口,负责与JDBC 驱动程序管理器API 进行通信,供应用程序开发人员使用(连接数据库,发送SQL 语句,处理结果)。 • (2) JDBC 驱动程序API:JDBC 驱动程序管理器与实际连接到数据库的第三方驱动程序进行通信(执行SQL 语句,返回查询信息)。供各开发商开发数据库驱动程序(JDBC Driver)使用。JDBC Driver 是一个类的集合,实现了JDBC 所定义的类和接口,提供了一个能实现java.sql.Driver 接口的类。
11.1.3 JDBC驱动程序 • JDBC 驱动可以分为下面四种类型,如图11-3 所示。 • 图11-3 四种类型的JDBC驱动程序
11.1.3 JDBC驱动程序 • 1. JDBC-ODBC桥,加上ODBC驱动程序(类型1) • 此驱动程序负责将JDBC转换为ODBC, 通过ODBC驱动程序来获得对数据库的JDBC访问。Sun 公司的Java 2 JDK 提供JDBC/ODBC 桥接器(sun.jdbc.odbc.JdbcOdbcDriver)。使用时必须先安装ODBC 驱动程序和配置ODBC 数据源。在JDBC 刚推出时,桥接器可以方便地用于测试,并不用于生产性的应用。目前,有很多更好的驱动程序,不建议使用桥接器。仅当特定的数据库系统没有相应的JDBC 驱动程序时使用。 • 2. 本地API,部分Java驱动程序(类型2) • 此驱动程序是个部分使用Java编程语言编写和部分使用本机代码编写的驱动程序,用于与数据库的客户机API进行通信。本地API驱动程序将JDBC命令转换为本地数据库系统的本地库方法,调用第三方数据库函数。使用时,除了安装Java库外,还必须安装某个特定数据库平台的代码(二进制代码,非Java)。
11.1.3 JDBC驱动程序 • 3. JDBC-Net,纯Java驱动程序(类型3) • 此驱动程序是个纯粹的Java客户程序库,使用跨数据库协议,将数据库访问请求传输给一个服务器组件,然后该中间件服务器将访问请求转换为特定数据库系统的协议,发送给数据库系统。该客户程序库是独立于实际数据而运行的,因此简化了对它的配置,如图11-4所示。 • 4. 本地协议,纯Java驱动程序(类型4) • 此驱动程序是个纯粹的Java驱动程序,直接与特定的数据库系统通信,直接将JDBC命令转换为数据库系统的本地协议。其优点是没有中间的转换或者是中间件。通常用于提高数据库访问的性能,如图11-5所示。
11.1.3 JDBC驱动程序 • 图11-4 第3种类型的JDBC驱动程序
11.1.3 JDBC驱动程序 • 图11-5 第四种类型的JDBC驱动程序
11.1.4 JDBC API • JDBC为Java语言提供一个调用级的接口,主要完成三个方面的功能:建立与数据库的连接;向数据库发送SQL语句;处理数据库返回结果。JDBC API调用流程关系如图11-6所示。 • 这些功能由一系列API 实现,其中主要的接口有驱动程序管理器(DriverManager)、驱动(Driver)、连接(Connection)、SQL 语句(Statement)和结果集(ResultSet)。
11.1.4 JDBC API • 图11-6 JDBC API 调用流程关系图
11.1.4 JDBC API • 1. DriverManager • DriverManager(java.sql.DriverManager)类处理驱动程序的加载,建立和管理应用程序与驱动程序之间的连接。它跟踪可用的驱动程序,并在数据库与相应的驱动程序之间建立连接,处理驱动程序的登录时间等相关事务。 • 建立与数据的连接,首先要创建指定数据库的URL,设定数据库的来源。数据库的URL 对象与网络资源的统一资源定位类似,格式如下: • jdbc:subProtocol:subName://hostname:port;DatabaseName=XXX;
11.1.4 JDBC API • 2. Driver • 每个数据库驱动程序必须实现Driver 接口。驱动程序由开发商提供,将应用程序的JDBC API 请求转换为特定的数据库请求。在编程时要连接数据库,必须先装载特定厂商提供的数据库驱动程序(Driver),即调用Class.forname()创建一个JDBC驱动器的实例。驱动程序的装载: • import java.sql.*; • Class.forName(driverName); //创建一个JDBC 驱动器的实例 • 【例11.2】加载驱动程序。 • import java.sql.*; • Class.forName("com.Microsoft.jdbc.sqlserver.SqlServerDriver"); • //装载MS SQLServer 驱动 • Class.forName("oracle.jdbc.driver.OracleDriver");//装载Oracle 驱动 • Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); • //装载JDBC-ODBC Bridge 驱动,在Java 2 SDK 中提供
11.1.4 JDBC API • 3. Connection • Connection(java.sql.Connection)用来表示数据连接的对象,对数据库的一切操作都是在这个连接的基础上进行的。它将应用程序连接到特定的数据库。可以使用Driver.connect方法建立连接。 • Connection con=Driver.connect(urlString, propertiesInfo); • 【例11.3】使用Driver.connest方法建立连接。 • Driver drv=new COM.cloudscape.coreRmiJdbcDrive(); • Connection con=null; • try{ • con=drv.connect(Jdbc:cloudscape:rmi:biceadb,null); • }catch(SQLException e){…} • Connection 类的主要的成员方法有以下几个。 • Statement createStatement():创建一个Statement 对象。 • void commit():提交对数据库的改动并释放当前连接的锁。 • void rollback():回滚当前事务中的所有改动并释放持有的数据库锁。 • void setReadOnly():设置连接的只读模式。 • void close():立即释放连接对象的数据库和JDBC 资源。
11.1.4 JDBC API • 4. Statement • Statement(java.sql.Statement)是在已经建立的连接上,向数据库发送SQL 语句的对象。它只是一个接口的定义,其中包括了执行SQL 语句和获取返回结果的方法。 • 有如下3种Statement 对象。 • Statement:用于执行不带参数的简单SQL 语句。 • PreparedStatement:用于执行带IN 参数和不带IN 参数的预编译SQL语句。 • CallableStatement:用于执行对数据库存储过程的调用。 • 它们都作为在给定连接上执行SQL 语句的容器,用于发送特定类型的SQL 语句。 • (1) Statement • 对象的创建方法为: • Statement stmt=con.createStatement();
11.1.4 JDBC API • 主要的成员方法如下。 • boolean execute(String sql):执行SQL 语句。 • ResultSet executeQuery(String sql):执行SELECT语句,数据库查询,返回结果集。 • int executeUpdate(String sql):执行INSERT、UPDATE、DELETE、DDL 语句,数据库更新。 • Connection getConnection():获取对数据库的连接。 • int getMaxRows():返回结果集的最大行数。 • ResultSet getResultSet():获取结果集。 • void close():关闭Statement语句指定的数据库连接。
11.1.4 JDBC API • (2) PreparedStatement • PreparedStatement 继承了Statement 接口。PreparedStatement 语句中包含预编译的SQL语句,因此可以获得更高的执行效率。特别是当需要反复调用某些SQL 语句时,使用PreparedStatement 语句具有明显优势。 • 另一方面,PreparedStatement 语句中,可以包含多个“?”代表的字段,在程序中利用set 方法设置该字段的内容,从而增强了程序的动态性。 • 对象的创建方法为: • PreparedStatement pstm=con.PrepareStatement(SQL语句);
11.1.4 JDBC API • (3) CallableStatement • CallableStatement 继承了PreparedStatement 接口。CallableStatement 对象用于执行对数据库中的存储过程的调用。在调用过程中可以使用设置IN参数向调用的存储过程提供执行所需的参数,通过OUT参数获取存储过程的执行结果。 • 对象的创建方法为: • CallableStatement cstm=con.prepareCall(sqlString); • 对象参数中调用以下存储过程。 • {call procedure_name}:不需要参数的存储过程调用。 • {call procedure_name[(?,?,?…)]}:需要若干参数的存储过程调用。 • {? = call procedure_name[(?,?,?…)]}:需要若干参数并有一个返回值的存储过程调用。
11.1.4 JDBC API • 5. ResultSet • ResultSet(java.sql.ResultSet)类用来暂时存放查询操作返回的数据结果集(包括行、列)。 • 它包含符合SQL 语句条件的所有行,使用get()方法对这些行的数据进行访问。对象的创建方法为: • Connection con=DriverManager.getConnection(urlString); • Statement stm=con.createStatement(); • ResultSet rs=stm.executeQuery(sqlString);
11.1.4 JDBC API • 此外,DatabaseMetadata类和ResultSetMetadata类(java.sql.DatabaseMetadata; java.sql.Result SetMetadata)用于查询结果集、数据库和驱动程序的元数据信息。 • Connection 提供了一个方法getMetadata()来获得数据库的元数据信息,它返回的是一个DatabaseMetadata 对象。通过DatabaseMetadata 对象,可以获得数据库的各种信息,如数据库厂商信息、版本信息、数据表数目、每个数据表名称,如:getDatabase ProductName()、getDatabaseProductVersion()、getDriverName()、getTables()等。
11.2 JDBC基本编程 • 11.2.1 连接数据库 • 11.2.2 加载驱动程序和创建连接 • 11.2.3 执行SQL语句 • 11.2.4 处理结果集 • 11.2.5 关闭数据库
11.2 JDBC基本编程 • 本节将介绍JDBC基本编程的相关内容,包括连接数据库、加载驱动程序和创建连接、执行SQL语句、处理结果集以及关闭数据库。
11.2.1 连接数据库 • 在创建JDBC应用之前,必须安装相应数据库的JDBC驱动程序。 • 1. 安装JDBC • 实际上,所有的数据库开发商都已经为数据库配备了JDBC 驱动程序。必须找到供应商使用的JDBC 驱动程序类的名字。 • 通常驱动程序的名字是: • com.Microsoft.jdbc.sqlserver.SQLServerDriver • oracle.jdbc.driver.OracleDriver • 然后,必须找到驱动程序所在的JAR 文件或ZIP 文件。将该驱动程序的完整路径添加在类路径(Classpath)上。可以修改CLASSPATH环境参数或将程序库文件复制到jre/lib/ext目录中。
11.2.1 连接数据库 • 2. 连接过程 • 首先引入JDBC 连接所需的类;加载JDBC 驱动程序;识别数据源(可选,JDBC 2.0 javax.sql.DataSource 接口支持);分配或创建一个连接对象Connection;分配或创建一个语句对象Statement;使用Statement 对象执行SQL 语句;从返回的ResultSet 对象中检索数据;关闭ResultSet 对象、Statement 对象、Connection 对象。建立到数据库的连接过程如图11-7 所示。
11.2.1 连接数据库 • 图11-7 建立到数据库的连接
11.2.1 连接数据库 • 连接过程的Java语句实现如下。 • (1) 加载JDBC 驱动类: • Class.forName("driverName"); • (2) 打开一个数据库连接: • DriverManager.getConnection("jdbc:xxx:datasource"); • (3) 执行SQL 语句: • stmt = con.createStatement(); • stmt.executeQuery("Select * from myTable"); • (4) 处理结果集Process result set: • while (rs.next()) • { • name = rs.getString("name"); • amount = rs.getInt("amt"); • }
11.2.1 连接数据库 • 3. 建立JDBC应用程序 • 创建任何一个JDBC应用程序,都需要以下6个步骤。 • (1) 加载一个JDBC驱动程序。 • (2) 建立与数据库的连接对象。 • (3) 建立一个语句对象。 • (4) 执行SQL语句。 • (5) 处理结果集。 • (6) 关闭所有JDBC对象。
11.2.2 加载驱动程序和创建连接 • 1. 加载驱动程序 • 在应用程序中,有三种方法可以加载驱动程序。 • (1) 利用System 类的静态方法setProperty() • System.setProperty("jdbc.drivers", "sun.jdbc.odbc.JdbcOdbcDriver"); • (2) 利用Class 类的静态方法forName() • Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); • Class.forName("oracle.jdbc.driver.OracleDriver"); • (3) 直接创建一个驱动程序对象 • new sun.jdbc.odbc.JdbcOdbcDriver();
11.2.2 加载驱动程序和创建连接 • 2. 建立与数据库的连接 • 利用DriverManager 类的静态方法getConnection()来获得与特定数据库的连接实例(Connection 实例)。 • Connection conn = DriverManager.getConnection(source); • Connection conn = DriverManager.getConnection(source, user, pass); • 其中的三个参数都是String 类型的,使用不同的驱动程序与不同的数据库建立连接时,source 的内容是不同的,但其格式是一致的,都包括用冒号隔开的三个部分: • jdbc:driverType:dataSource • 对于JDBC-ODBC Bridge,driverType 为odbc, dataSource 则为ODBC 数据源:“jdbc:odbc:myDSN”。对于其他驱动程序,数据库系统不同,driverType 和dataSource 有不同的格式和内容。
11.2.3 执行SQL语句 • 每执行一条SQL 语句,都需要利用Connetcion 实例的createStatement()方法来创建一个Statement实例。Statement 的常用方法包括:执行SQL INSERT、UPDATE或DELETE等语句,int executeUpdate(String sql)执行SQL SELECT语句ResultSet executeQuery (Stringsql),执行一个可能返回多个结果的SQL 语句boolean execute(Stringsql) (与其他方法结合起来获得结果)。Statement 中还有其他的方法来执行SQL 语句。
11.2.4 处理结果集 • 通过ResultSet可以获得查询结果。 • ResultSet 实例最初定位在结果集的第一行(记录)。 • ResultSet 提供了一些在结果集中定位的方法,如next()等。 • ResultSet 提供了一些方法来获得当前行中的不同字段的值,如getXXX()。 • ResultSet 中还提供了有关方法来修改结果集,并提交到数据库中去。 • ResultSet 对象常用的get 方法的参数为int colIndex 或String colName • 确定了字段类型,获取字段数据时,就可以明确如何使用ResultSet 中的getXXX()方法了。ResultSet常用的getXXX方法如表11-2所示。
11.2.4 处理结果集 • 表11-2 ResultSet中常用的getXXX方法
11.2.4 处理结果集 • 通过ResultSetMetadata 来获得查询结果的元数据信息ResultSet 提供了一个方法getMetadata()来获得结果集的元数据信息,它返回的是一个ResultSetMetadata 实例。 • 通过ResultSetMetadata 实例,就可以获得结果集中字段的详细信息,如字段总数,每个字段的名称、类型等。 • getColumnCount():返回列数。 • getColumnName(i):返回列名。 • getColumnType(i):返回列数据类型。 • getColumnLabel(i):返回列的标签。 • getTableName():返回表名。
11.2.5 关闭数据库 • 数据库访问结束后,需要关闭已打开的JDBC 对象,释放占用的资源。 • 【例11.11】关闭数据库。 • try • { • rs.close(); • stm.close(); • con.close(); • } • catch (SQLException e) • { • e.printStackTrace(); • }
11.3 JDBC编程实例 • 11.3.1 建立连接 • 11.3.2 数据库操作 • 11.3.3 JDBC2.0中的数据源
11.3 JDBC编程实例 • 在11.2节的讲解基础上,本节将通过具体的例子来介绍如何使用JDBC进行数据库操作。
11.3.1 建立连接 • 文件:database.properties • // ==================== Program Discription ====================== • // 文件名称:database.properties • // 文件目的:存储连接数据库所需的属性信息,可根据不同的数据库信息设置 • // ============================================================== • jdbc.drivers=COM.cloudscape.core.JDBCDriver • jdbc.url=jdbc:cloudscape:COREJAVA;create=true • jdbc.username= • jdbc.password= • 文件:TestDB.java • // ==================== Program Discription ====================== • // 程序名称:TestDB.java • // 程序目的:利用JDBC 连接数据库 • // ============================================================== • import java.sql.*; • import java.io.*; • import java.util.*; • /**
11.3.1 建立连接 • 本程序测试数据库和JDBC 驱动是否正确安装。 • */ • class TestDB • { • public static void main(String args[]) • { • try • { • Connection conn = getConnection(); • Statement stat = conn.createStatement(); • stat.execute("CREATE TABLE Greetings(Name CHAR(20))"); • stat.execute( • "INSERT INTO Greetings VALUES('Hello, World!')"); • ResultSet result • = stat.executeQuery("SELECT * FROM Greetings"); • result.next(); • System.out.println(result.getString(1)); • result.close(); • stat.execute("DROP TABLE Greetings"); • stat.close(); • conn.close();
11.3.1 建立连接 • } • catch (SQLException ex) • { • while (ex != null) • { • ex.printStackTrace(); • ex = ex.getNextException(); • } • } • catch (IOException ex) • { • ex.printStackTrace(); • } • } • /** • 从database.properties 文件中获取连接的属性信息,返回一个数据库连接 • */ • public static Connection getConnection() • throws SQLException, IOException • {
11.3.1 建立连接 • Properties props = new Properties(); • FileInputStream in • = new FileInputStream("database.properties"); • props.load(in); • in.close(); • String drivers = props.getProperty("jdbc.drivers"); • if (drivers != null) • System.setProperty("jdbc.drivers", drivers); • String url = props.getProperty("jdbc.url"); • String username = props.getProperty("jdbc.username"); • String password = props.getProperty("jdbc.password"); • return • DriverManager.getConnection(url, username, password); • } • }
11.3.2 数据库操作 • // ==================== Program Discription ========================== • // 程序名称:User.java • // 程序目的:创建一个用来操作用户信息的类 • // ============================================================== • public class User • { • private String username; • private String password; • private String regDate; • // 获取用户名 • public String getUsername() • { • return username; • } • // 设置用户名
11.3.2 数据库操作 • public void setUsername(String username) • { • this.username = username; • } • // 获取用户密码 • public String getPassword() • { • return password; • } • // 设置用户密码 • public void setPassword(String password) • { • this.password = password; • } • // 获取用户注册时间 • public String getRegDate() • { • return regDate; • } • // 设置用户注册时间 • public void setRegDate(String regDate) • { • this.regDate = regDate; • } • }
11.3.2 数据库操作 • // ==================== Program Discription ========================== • // 程序名称:UserMgr.java • // 程序目的:利用JDBC 对数据库进行增删查改操作 • // ============================================================= • import java.sql.*; • import test.DBConnection; • public class UserMgr • { • // 向数据库中添加用户信息 • public boolean addUser(User user) • { • // 构造SQL 语句 • String sql="insert into tbl_user (vcUsername,vcPassword,dtRegDate) • values('"+user.getUsername()+"','" • +user.getPassword()+"',getDate())"; • Statement stmt; • Connection conn; • try • { • // 获取数据库连接 • conn = DBConnection.getConnection(); • // 创建Statement 对象 • stmt = conn.createStatement();