Post on 07-Jan-2016
description
第 16 讲 利用 JDBC 实现 Java 程序与数据库的连接
16.1 JDBC 概述16.2 JDBC 驱动程序16.3 JDBC 常用类与方法16.4 数据库访问过程
本本本点
了解 JDBC 的基本概念 了解 JDBC 的几种常用驱动程序 了解 JDBC 的常用类与方法,掌握在与数据库
连接经常使用的类与法 掌握 JDBC 访问数据库的基本方法
16.1 JDBC 概述
Java 定义了一个通用的 SQL 数据库存取框架,在各种各样的数据库连接模块上提供统一的界面,使与数据库无关的 Java 工具和产品成为可能,使得数据库连接的开发者可以提供各种各样的连方案。这一通用的 SQL 数据库存取框架就是 JDBC 。 JDBC 的设计者以 X/open SQL Call Level Interface( 调用层接口 ) 做为 API 的基础,它也是 Microsoft's ODBC (开放数据库互连)的基础。
16.2 JDBC 应用 与数据库建立连接 ,发送 SQL 语句 ,处理结果。
Connection con = DriverManager.getConnection ("jdbc:odbc:wombat", "login", "password");Statement stmt = con.createStatement();ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");while (rs.next())System.out.println(rs.getString("a") + " " + rs.getString("b") + " " + rs.getString("c"));
JDBC 是一种低级 API ,是高级 API 的基础
16.3 两层模型和三层模型 JDBC API 既支持数据库访问的两层模型,同时也支持三层模型。 在两层模型中, Java applet 或应用程序将直接与数据库进行对话。这将需要一个 JDBC 驱动程序来与所访问的特定数据库管理系统进行通讯。用户的 SQL 语句被送往数据库中,而其结果将被送回给用户。数据库可以位于另一台计算机上,用户通过网络连接到上面。这就叫做客户机 / 服务器配置,其中用户的计算机为客户机,提供数据库的计算机为服务器。网络可以是 Intranet (它可将公司职员连接起来),也可以是 Internet 。 在三层模型中,命令先是被发送到服务的“中间层”,然后由它将 SQL 语句发送给数据库。数据库对 SQL 语句进行处理并将结果送回到中间层,中间层再将结果送回给用户。 MIS 主管们都发现三层模型很吸引人,因为可用中间层来控制对公司数据的访问和可作的的更新的种类。中间层的另一个好处是,用户可以利用易于使用的高级 API ,而中间层将把它转换为相应的低级调用。最后,许多情况下三层结构可提供一些性能上的好处。
16.2.3 JDBC 产品有关最新的信息,请查阅 JDBC 的网站,可通过从以下 URL 开始浏览找到:http://java.sun.com/products/jdbc 1 JavaSoft 框架 JavaSoft 提供三种 JDBC 产品组件,它们是 Java 开发工具包 (JDK) 的组成部份: JDBC 驱动程序管理器, JDBC 驱动程序测试工具包,和 JDBC-ODBC 桥。 2 JDBC 驱动程序的类型 JDBC-ODBC 桥加 ODBC 驱动程序: JavaSoft 桥产品利用 ODBC 驱动程序提供 JDBC 访问。本地 API - 部份用 Java 来编写的驱动程序 JDBC 网络纯 Java 驱动程序 本地协议纯 Java 驱动程序
16.3 JDBC 常用类与方法之一 1、 DriverManager 类: 负责管理 JDBC 驱动程序。使用 JDBC 驱动程序之前,必须先将驱动程序加载并向 DriverManager注册后才可以使用,同时提供方法来建立与数据库的连接。
方法: A、 Class.forName(String driver); //加载注册驱动程序 B、 Static Connection getConnection(String url,String user,String password) throws SQLException; // 取得对数据库的连接 C、 Static Driver getDriver(String url) throws SQLExcetion; // 在已经向 DriverManager注册的驱动程序中寻找一个能够打开 url 所指定的数据库的驱动程序
16.3 JDBC 常用类与方法之二
2、 Connection 类 负责维护 JSP/JAVA 数据库程序和数据库之间的联机。可以建立三个非常有用的类对象。 方法: A、 Statement createStatement() throws SQLException; // 建立 Statement 类对象 Statement createStatement(int resultSetType,int resultSetConcurrency) throws SQLException; // 建立 Statement 类对象 resultSetType值 TYPE_FORWARD_ONLY 结果集不可滚动 TYPE_SCROLL_INSENSITIVE 结果集可滚动,不反映数据库的变化 TYPE_SCROLL_SENSITIVE 结果集可滚动,反映数据库的变化 resultSetConcurrency值 CONCUR_READ_ONLY 不能用结果集更新数据 CONCUR_UPDATABLE 能用结果集更新数据 JDBC2.0中才支持滚动的结果集,而且可以对数据进行更新 B、 DatabaseMetaData getMetaData() throws SQLException; // 建立 DatabaseMetaData 类对象 C、 PreparedStatement prepareStatement(String sql) throws SQLException; // 建立 PreparedStatement 类对象 D、 boolean getAutoCommit() throws SQLException //返回 Connection 类对象的 AutoCommit状态 E、 void setAutoCommit(boolean autoCommit) throws SQLException // 设定 Connection 类对象的 AutoCommit状态 F、 void commit() throws SQLException //确定执行对数据库新增、删除或修改记录的操作 G、 void rollback() throws SQLException // 取消执行对数据库新增、删除或修改记录的操作 H、 void close() throws SQLException // 结束 Connection 对象对数据库的联机 I、 boolean isClosed() throws SQLException //测试是否已经关闭 Connection 类对象对数据库的联机
16.3 JDBC 常用类与方法之三 3、 Statement 类 通过 Statement 类所提供的方法,可以利用标准的 SQL 命令,对数据库直接新增、删除或修改操作 方法: A、 ResultSet executeQuery(String sql) throws SQLException //使用 SELECT 命令对数据库进行查询 B、 int executeUpdate(String sql) throws SQLException // 使用 INSERT\DELETE\UPDATE 对数据库进行新增、删除和修改操作。 C、 void close() throws SQLException // 结束 Statement 类对象对数据库的联机
16.3 JDBC 常用类与方法之四 4、 PreparedStatement 类
PreparedStatement 类和 Statement 类的不同之处在于 PreparedStatement 类对象会将传入的 SQL 命令事先编好等待使用,当有单一的 SQL指令比多次执行时,用 PreparedStatement 类会比 Statement 类有效率 方法:A、 ResultSet executeQuery() throws SQLException // 使用 SELECT 命令对数据库进行查询 B、 int executeUpdate() throws SQLException // 使用 INSERT\DELETE\UPDATE 对数据库进行新增、删除和修改操作。 C、 ResultSetMetaData getMetaData() throws SQLException // 取得 ResultSet 类对象有关字段的相关信息 D、 void setInt(int parameterIndex,int x) throws SQLException // 设定整数类型数值给 PreparedStatement 类对象的 IN参数 E、 void setFloat(int parameterIndex,float x) throws SQLException // 设定浮点数类型数值给 PreparedStatement 类对象的 IN参数 F、 void setNull(int parameterIndex,int sqlType) throws SQLException // 设定 NULL 类型数值给 PreparedStatement 类对象的 IN参数 G、 void setString(int parameterIndex,String x) throws SQLException // 设定字符串类型数值给 PreparedStatement 类对象的 IN参数 H、 void setDate(int parameterIndex,Date x) throws SQLException // 设定日期类型数值给 PreparedStatement 类对象的 IN参数 I、 void setTime(int parameterIndex,Time x) throws SQLException // 设定时间类型数值给 PreparedStatement 类对象的 IN参数
16.3 JDBC 常用类与方法之五 5、 DatabaseMetaData 类
DatabaseMetaData 类保存了数据库的所有特性,并且提供许多方法来取得这些信息。方法:A、 String getDatabaseProductName() throws SQLException // 取得数据库名称 B、 String getDatabaseProductVersion() throws SQLException // 取得数据库版本代号 C、 String getDriverName() throws SQLException // 取得 JDBC 驱动程序的名称 D、 String getDriverVersion() throws SQLException // 取得 JDBC 驱动程序的版本代号 E、 String getURL() throws SQLException // 取得连接数据库的 JDBC URL F、 String getUserName() throws SQLException // 取得登录数据库的使用者帐号
16.3 JDBC 常用类与方法之六 6、 ResultSet 类 负责存储查询数据库的结果。并提供一系列的方法对数据库进行新增、删除和修改操作。也负责维护一个记录指针( Cursor ),记录指针指向数据表中的某个记录,通过适当的移动记录指针,可以随心所欲的存取数据库,加强程序的效率。方法:A、 boolean absolute(int row) throws SQLException //移动记录指针到指定的记录 B、 void beforeFirst() throws SQLException //移动记录指针到第一笔记录之前 C、 void afterLast() throws SQLException //移动记录指针到最后一笔记录之后 D、 boolean first() throws SQLException //移动记录指针到第一笔记录 E、 boolean last() throws SQLException //移动记录指针到最后一笔记录 F、 boolean next() throws SQLException //移动记录指针到下一笔记录 G、 boolean previous() throws SQLException //移动记录指针到上一笔记录 H、 void deleteRow() throws SQLException //删除记录指针指向的记录 I、 void moveToInsertRow() throws SQLException //移动记录指针以新增一笔记录 J、 void moveToCurrentRow() throws SQLException //移动记录指针到被记忆的记录 K、 void insertRow() throws SQLException // 新增一笔记录到数据库中 L、 void updateRow() throws SQLException //修改数据库中的一笔记录 M、 void update 类型 (int columnIndex, 类型 x) throws SQLException //修改指定字段的值 N、 int get 类型 (int columnIndex) throws SQLException // 取得指定字段的值
O、 ResultSetMetaData getMetaData() throws SQLException // 取得 ResultSetMetaData 类对象
16.3 JDBC 常用类与方法之七 7 、 ResultSetMetaData 类 ResultSetMetaData 类对象保存了所有 ResultSet 类对象中关于字段的信息,提供许多方法来取得这些信息。 方法: A、 int getColumnCount() throws SQLException // 取得 ResultSet 类对象的字段个数 B、 int getColumnDisplaySize() throws SQLException // 取得 ResultSet 类对象的字段长度 C、 String getColumnName(int column) throws SQLException // 取得 ResultSet类对象的字段名称 D、 String getColumnTypeName(int column) throws SQLException // 取得 ResultSet 类对象的字段类型名称 E、 String getTableName(int column) throws SQLException // 取得 ResultSet 类对象的字段所属数据表的名称 F、 boolean isCaseSensitive(int column) throws SQLException //测试 ResultSet类对象的字段是否区分大小写 G、 boolean isReadOnly(int column) throws SQLException //测试 ResultSet 类对象的字段是否为只读
16.4 数据库访问过程 16.4.1 JDBC<-->ODBC 访问的流程
JDBC Driver Mannager->JDBC<->ODBC桥 ->ODBC->数据库客户机驱动库 ->数据库服务器 -> 返回查询结果,在这种访问中值的我们注意的是虽然 JAVA 是“Write Once ,Run Anywhere” ,但是如果通过这种访问的话,需要客户端必须设置 ODBC 和有相应的数据库客户机的驱动。
由于不是所有的数据库服务器提供商都提供 JDBC 驱动程序(给 JDBC 访问提供相应的接口),所以就有了 JDBC<->ODBC Bridge 。
16.4 数据库访问过程之二 16.4.2 JDBC 驱动返回查询结果
JDBC Driver Mannager-> 局部 JDBC 驱动 ->客户端数据库 ->数据库服务 JDBC 驱动返回查询结果器 -> 返回查询结果,这种访问事实上是转换 JDBC 调用为相应的数据库( Oracle, Sybase, Informix, DB2, 和其他的数据库数据库管理系统)的客户端 API 调用,这种方式的访问需要相应的数据库提供商提供相应的 JDBC 驱动程序,但是有一种好处,可以独立于 odbc 用于可以随处可 Run 的客户端的浏览器中的 Applet 程序。
16.4.3 JDBC 连接举例 以连接一个 SQLSever 数据库为例
设置 odbc:打开 odbc 数据源 ->选择系统 dsn(Click 加新的 dsn-)->接下来输入选择数据库类型、输入 dsn名 :、选择服务器、连接数据库的方式、输入数据库的登陆用户和密码 ->测试连接,如果测试成功的话,那么 dsn 就建立好了,假定 dsn名为 Sqlserver. 使用的是 sqlserver2000, 以 “ sa”登陆,密码为空。
16.4.3 JDBC 连接举例(续一) import java.sql.*;
//加载 java 数据连接包, java 基本所有的数据库的调用的都在这个东西里面
public class InsertCoffees {
public static void main(String args[]) {
String url = "jdbc:odbc:sqlserver"; // 取得连接的 url名,注意 sqlserver 是 dsn名 Connection con; //实例化一个 Connection 对象 Statement stmt; String query = "select * from col_link"; //选择所有的 Col_link 表中的数据输出
16.4.3 JDBC 连接举例(续二) try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载 jdbc-odbc桥驱动
} catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); //加载 jdbc-odbc桥错误 System.err.println(e.getMessage()); // 其他错误 }
try {
con = DriverManager.getConnection(url, "sa", ""); // 数据库连接
16.4.3 JDBC 连接举例(续三) stmt = con.createStatement();
//Create 一个声明 stmt.executeUpdate("CREATE TABLE col_link (sitename varchar (20) NULL ,siteurl varchar (50) NULL) "); //执行了一个 sql 语句生成了一个表 col_link的表 stmt.executeUpdate("insert into col_link values('ASP 中华网 ','http://www.aspcn.com')"); stmt.executeUpdate("insert into col_link values('永远到底有多远 ','http://xuankong.com')"); //执行一个 insert into 语句 stmt.executeUpdate("update col_link set siteurl='http://www.aspcn.com/xuankong/xuankongt.jpg' where siteurl='http://xuankong.com'"); //执行一个 update 语句,更新数据库 ResultSet rs = stmt.executeQuery(query); //返回一个结果集
16.4.3 JDBC 连接举例(续四) System.out.println("Col_link表中的数据如下 (原始数据 )");
// 下面的语句使用了一个 while循环打印出了 col_link表中的所有的数据 System.out.println("站点名 "+" "+"站点地址 "); System.out.println("---------------"+" "+"----------------"); while (rs.next()) { String s = rs.getString("sitename"); String f = rs.getString("siteurl"); // 取得数据库中的数据 System.out.println(s + " " + f); /*String t = rs.getString(1); String l = rs.getString(2); System.out.println(t + " " + l);*/ /*jdbc 提供了两种方法识别字段,一种是使用 getXXX(注意这里的 getXXX表示取不同类型字段的不同的方法 )获得字段名, 第二种 *是通过字段索引,这里把第二种方法注释了 */
16.4.3 JDBC 连接举例(续五) /*可以访问这个连接获得 getxxx 的用法: http://java.sun.com/docs
/books/tutorial/jdbc/basics/_retrievingTable.html*/ } stmt.close(); con.close(); // 上面的语句关闭声明和连接 } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); //显示数据库连接错误或者查询错误 } } }