1、第7章 数据库编程,学习导读 本章将介绍JDBC数据库连接技术,以及使用JDBC进行数据库应用程序开发的主要步骤,并基于多种数据库实例进行应用分析。包括:JDBC包中的类、接口JDBC编程步骤及要领数据库的基本设计(表, SQL, 存储过程),7.1 数据库基础7.1.1 关系数据库7.1.2 SQL基本内容7.1.3 ODBC技术7.2 JDBC数据库连接技术 7.2.1 JDBC概述 7.2.2 JDBC的实现及其驱动程序 7.2.3 JDBC的常用类和接口 7.3 Java访问数据库的基本步骤 7.3.1 加载驱动程序类 7.3.2 建立JDBC连接 7.3.3 执行SQL语句,7.4
2、JDBC高级特性 7.4.1 预备语句 7.4.2 可滚动和可更新的结果集 7.4.3 元数据 7.4.4 事务 7.5 创建数据库 7.6 JDBC综合应用举例,关系数据库1. 基本概念 包括 关系、元组、属性、域,以及主键、外键和关系模式.2. 关系的完整性实体完整性,域完整性和参照完整性.3. 关系运算专门的关系运算包括:选择、投影和连接.,7.1 数据库基础,SQL基本内容结构化查询语言(SQL)在数据库级实现了DDL,DML和DCL功能。例如,1)创建数据库表 2)创建数据查询,包括create、select、insert、update和delete、drop语句。在SQL语句中,可
3、以使用各种关系运算符,以及在SQL语言级的一些运算符和语句。例如,and、or、between and、like、join on等。下面是各种常用语句.,ODBC技术-开放式数据库连接 一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应DBMS的ODBC驱动程序完成。 不论是Access、SQL Server还是Oracle数据库,都需要建立相应的数据源,应用程序和物理数据库之间的通信则由ODBCAPI协调完成。 ODBC的优点是能以统一的方式处理所有的关系型数据库。ODBC的对象是基于关系型的数据源,它本身提供了对SQL语言的支持。但对
4、非关系数据库支持不够。,1. 基本概念JDBC API是建立在微软ODBC抽象层的基础上,它屏蔽了各种异构数据库,在Java中提供了统一的数据库连接和访问技术。同时由于Java 语言的跨平台性,使得基于Java的数据库应用程序具有很好的可移植性。 JDBC与ODBC之不同ODBC只限于Windows平台,而JDBC驱动作用在现有的驱动程序之上,具有跨平台性.JDBC不需要配置数据源,在程序中直接指定.,7.2 JDBC连接技术,2. JDBC实现及其驱动程序,除了使用JDBC-ODBC方式,还常使用专用驱动程序连接。像mySQL、SQLServer、Oracle、Sybase等数据库都提供了专
5、用驱动程序。,通过用专用网络协议创建的驱动程序与数据库直接通信:,通过JDBC-ODBC桥与ODBC数据源通信:,通过数据库厂商提供的专用驱动程序:,JDBC提供4种驱动程序,其中JDBC-ODBC桥接方式和数据库协议驱动程序方式使用得最多。前者的使用格式是统一的,例如: Driver: “sun.jdbc.odbc.JdbcOdbcDriver” URL: “jdbc:odbc:datasource” 而后者要看具体数据库厂商提供者的实现。如图所示描述了JDBC的结构。,左图中可以代表什么呢?我们即将要做的事情.?,下面分别是JDBC API,Java数据库连接图。,3. 常用类和接口JDB
6、C API所有的类和接口都集中在java.sql和javax.sql这两个包中。其功能可以生成连接、执行语句、准备语句和运行批处理查询等。javax.sql包在java.sql包的基础上,修改了有关JDBC编程体系结构方面的内容,并且为连接管理、分布式事务处理提供了更好的抽象。同时,这个包还引入了容器管理的连接缓冲池等机制。下面介绍 DriverManager类、Connection接口(也是一种”类”)、Statement接口和ResultSet接口,以及它们的常用方法。,一般地,数据库在建立连接时都要求指定用户名和密码,否则将出现连接失败.,语句(Statement)用于对数据库发送数据操
7、纵的命令,通过语句对象,可以完成获取结果集、对数据库记录进行增、删、改、查操作(ADES)。语句分为3种类型:StatementPreparedStatementCallableStatement,像executeQuery会返回一个动态记录集ResultSet,然后应用程序再通过记录集指针的next()读取每一条记录。像Connection,Statement,ResultSet都是接口,它们是如何被使用的?在应用程序中是如何得到这些对象的?,使用JDBC技术访问物理数据库,主要分为以下三个步骤: 首先,需要指定数据源和装载驱动程序; 其次,指定数据库URL,与数据库建立连接; 最后,执行S
8、QL语句,并获得执行结果。 下面分别予以介绍.,7.3 Java访问数据库的基本步骤,(1)加载驱动程序类 首先,指定或定义数据源,依据驱动程序类型加载相应的JDBC驱动程序类。 (1)使用通用型JDBC-ODBC驱动此时,驱动程序类名是sun.jdbc.odbc.JdbcOdbcDriver,已由JDK提供,因此无须再安装。 (2)专用驱动此时,驱动程序类依赖于数据库厂商提供者。例如,SQL Server提供者类:com.microsoft.jdbc.sqlserver.SQLServerDriverOracle提供者类:oracle.jdbc.driver.OracleDriver 然后,
9、使用以下方式之一加载驱动程序。, 显式加载驱动类来注册驱动程序 例如, Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”); 或者,Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”); 使用java命令行参数设置jdbc.drivers属性java -Djdbc.drivers = com.microsoft.jdbc.sqlserver.SQLServerDriver MyJavaClass 在程序中通过方法调用来设置系统属性例如,System.setProperty(“jdbc.
10、drivers”, “com.microsoft.jdbc.sqlserver. SQLServerDriver”);还可以直接建立一个驱动程序对象,例如: new com.microsoft.jdbc.sqlserver. SQLServerDriver();,对于那些专用驱动类,通常以.jar文件出现,因此要将这些包置于以下路径之一:使用-classpath命令行参数启动数据库程序。修改classpath环境变量。将数据库的驱动程序包复制到JDK安装目录的jre/lib/ext目录中。 想想看,上述做法的理由是什么?,例如,对于SQL Server2000的驱动,需要从微软网站下载JDBC
11、 for SQL Server2000,解压后有3个jar文件用于访问SQL Server2000所需类库。下面显示了添加到classpath环境变量中去的3个jar文件。例如, 想想看,最好的做法是哪一种?,(2)建立连接在连接数据库时,必须指定数据源以及各种附加参数。例如,网络协议的驱动程序需要设置端口,而ODBC驱动程序则需要设置各种属性。JDBC使用了一种与普通URL相类似的语法来描述数据源。即jdbc:subprotocol:subname 其中,subprotocol用于指明连接到数据库的特定驱动程序 如果使用JDBC-ODBC驱动,JDBC URL将以jdbc:odbc开始。 如
12、果使用专用驱动,JDBC URL将依赖于具体提供者。一般以 “jdbc:数据库产品名:”打头。,在注册了驱动程序和指定数据库的URL之后,就可以使用DriverManager类的类方法getConnection()获得连接对象,打开到数据库的连接了。例如,使用直连SQL Server方式:Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);String url=“jdbc:sqlserver:/(local):1433; databaseName= bookdb”;Connection conn= DriverManage
13、r.getConnection (URL, username, psd);. 驱动程序管理器将遍历当前所有已经注册过的驱动程序,以便找到一个能够使用数据库URL中设定的subprotocol的驱动程序。,(3)执行SQL语句 在执行SQL命令之前,首先,需要创建一个Statement对象。使用Connection对象的createStatement()方法可以创建一个Statement对象。例如, Statemenr stat = conn.createStatement (); 然后,指定SQL字符串的内容。例如, String cmd =update books +SET price =
14、price +5 where bookname like Java高级% ; 之后,调用Statement类中的相应方法执行SQL语句。上述update语句将调用 executeUpdate方法: stat.executeUpdate (cmd); 在本步骤中,将所有不再使用的JDBC对象逐一关闭。例如使用完了的连接对象、语句对象和记录集对象等。,关于executeUpdate语句 上述executeUpdate方法将返回受SQL命令影响的行数。例如,在上述例子中调用executeUpdate方法将返回那些增加5元的书名以“Java高级”打头的图书总数。 executeUpdate()方法既可
15、以执行诸如insert,update和delete之类的操作,也可以执行诸如CREATE TABLE和DROP TABLE之类的数据定义命令。 下面分别举例说明JDBC-ODBC在不同数据库上的访问情形。首先,介绍在Access数据库中的应用。,【例7.1】 使用JDBC-ODBC访问Access数据库,在Access数据库访问程序之前, 请创建 MS office ACCESS2003数据库ODBC数据源,取名book5。对应的数据库文件是bookTest.mdb。程序如下:,下面介绍JDBC-ODBC访问SQL Server2000数据库的情形.,【例7.2】 使用JDBC-ODBC访问S
16、QL Server数据库,程序运行结果,【例7.3】 使用JDBC-ODBC访问Oracle 10g数据库,下面介绍JDBC-ODBC访问Oracle 10g数据库的情形.,程序运行结果,对于SQL Server、Oracle、mySQL等数据库,这些数据库厂商还提供了专用连接方式,下面分述之。,程序运行结果,对于SQLServer专用驱动,可从MS网站下载安装包SQLServer2000 Driver for JDBC.exe,解压后得到3个jar文件。并为SQL Server 2000下载SP4补丁SQL2000.MSDE-KB884525-SP4-CHS.EXE,并安装之。 对于Orac
17、le专用驱动,可从oracle官网下载程序包ojdbc14-10.2.0.2.jar,其中包含了直连Oracle方式所需类库。此时,Oracle的连接字符串格式是:jdbc:oracle:thin: : : 注意,这些JDBC for SQLServer2000或for Oracle的类库应该放在合适的位置!,为使JDBC for SQL Server 2000能够正常工作,必须完成两项设置: 一是,下载SQL Server 2000专用驱动程序包; 二是,为SQL Server 2000 打补丁sp4. 这两个设置缺一不可。 下面分别完成上述两项操作.,一,下载JDBC for SQL Se
18、rver 2000专用驱动程序包,并置于如图所示位置:,二,为SQL Server2000安装sp4补丁,查看更新后的SQL Server2000版本,查看1433端口是否打开,下面举例说明JDBC直连SQL Server2000数据库的访问情形.,【例7.4】 使用JDBC直连SQL Server2000数据库,下面举例说明JDBC直连Oracle 10g数据库的访问情形.,【例7.5】 使用JDBC直连Oracle 10g数据库,程序运行结果,读者可根据SQL Server2000的直连方式,编写直连Oracle 10g的数据库代码。,本程序在运行过程中可能出现的异常:,也可以为那些需要连
19、接对象的JDBC数据库应用程序设计一个连接类,在需要的时候获取这样一个对象资源即可。例如,,想想看,通过上述代码应该如何得到一个连接对象?,附 常用数据库专用驱动及URL,预备语句- (Prepared Statement) 如果要多次执行一个SQL语句,它们仅仅是参数不同罢了。为提高SQL的语句的执行效率,JDBC提供了一个参数化的SQL语句对象PreparedStatement,进行带参数的数据库查询。 对PreparedStatement而言,SQL语句中一些变化的数据在创建时被作为一个参数提供,然后在被编译后存放在数据库中。因此,在执行PreparedStatement语句时,无须再次
20、编译,只要将相应的参数值传递进去执行即可,其执行速度要快于Statement对象。,7.4 JDBC高级特性,例如,如果要查询指定出版社的图书,其SQL语句应该是:String cSQL = select name, price, publisher from books where books.publisher =清华大学; 对于此类查询,没有必要每次都建立新的查询语句,可以使用预装入参数的方式进行优化。用一个?代表一个参数,每次查询时只需为该参数填入不同的值就可以重复使用该语句。也允许指定多个参数,在执行该语句之前它们依序被赋值! 因此,上述静态SQL语句改写成动态SQL语句后,如下所示
21、: String pSQL=select name, price, publisher from books where publisher = ? ; 所需创建的PreparedStatement对象是:PreparedStatement pstat = conn.prepareStatement (pSQL);,在执行预备语句之前,必须使用set方法将参数绑定到实际的值上。例如,为出版社名称设置了一个字符串值。pstat.setString (1, 清华大学);ResultSet rs= pstat.executeQuery(); 这里参数类型为字符串,所以使用setString()方法,
22、类似的,还有很多set()方法可用与不同类型参数值的设定。例如,setBoolean(), setInt(), setLong(), setDouble(), setDate()等方法。这些方法均要求2个参数,第一个参数指出预备语句中参数的出现顺序(依次编号为1,2,.),第二个参数为赋予该参数的值。下面举例说明之应用.,【例7.6】 使用预备语句与JDBC直连SQLServer数据库,程序运行结果?,对于那些SQL更新语句,就调用预备语句的executeUpdate()方法。在JDBC中使用存储过程除了在JDBC应用程序中直接使用SQL语句编写数据库访问代码之外,还可以在数据库一端将SQL代
23、码组织在存储过程中,然后在JDBC应用程序中调用它们,获取数据结果集和一些返回值。可以创建SQL Server存储过程和Oracle存储过程。下面举例说明在JDBC中使用这两种存储过程。,【例7.7】 使用SQLServer存储过程编写JDBC应用程序,为了访问存储过程,需使用CallableStatement语句对象,如果还需要返回值,应该使用语法 “?= call 存储过程名(?,?,.)”。对于带返回结果集和输出参数的SQLServer存储过程的调用,应注意先获取结果集。还有不带结果集、或既有输入参数也有输出参数等情形。请思考,如何编写这样的JDBC程序?,程序运行结果,Java JDB
24、C调用Oracle存储过程一般有3种: 1.无返回值 2.有一个返回值 3.返回一个数据集,就是游标! 在Java中调用存储过程的语法是: call 语法格式 call 存储过程名(参数列表)想想看,Java Jdbc调用SQLServer存储过程的一般形式呢?还可以这样: ? = call SQLProcedure(?,?,?),小结-可滚动和可更新记录集为了从查询中获得可滚动的结果集,必须使用以下方法得到一个不同的Statement对象: Statement stat = conn.createStatement ( type, concurrency); 如果要获得预备语句,请调用以下方
25、法: PreparedStatement stat = conn.prepareStatement (command, type, concurrency);,元数据 如果在开发数据库应用程序时使用了事先定义好的数据库,那么数据库的结构和表信息就不是非常有用了。毕竟,在设计数据库表时,就已经知道了它们的结构。但是,对于那些编写数据库工具的开发人员来说,数据库的结构信息却是极其有用的。,例如,使用下列方法从数据库连接中获取一个DatabaseMetaData对象。DatabaseMetaData meta = conn.getMetaData ();现在就可以获取某些元数据了。例如调用下列方法;
26、ResultSet mrs = meta.getTables(null, null, null, new String TABLE);将返回一个包含所有数据库表信息的结果集。该结果集中的每一行都包含了数据库中一张表的详细信息。如果只想取第三列,即表名称,则使用 mrs.getString(3)就可以获得表名称。下面举例说明其应用.,【例7.9】 获取连接对象的元信息,程序运行结果,事务 可以将一组语句构成一个事务。当所有语句都顺利执行之后,事务可以被提交(commit)。否则,如果其中某个语句遇到错误,那么事务将被回滚(rollback),就好像没有执行过任何命令一样。 将多个命令组合成事务的
27、主要原因是为了确保数据库的完整性。例如,假设需要完成一个转账业务。此时,一个非常关键的问题就是必须确保将钱从一个账号取出并且成功存入另一个账号。如果在将钱存入其他账号之前系统发生崩溃,那么必须撤销取款操作。 事务操作具有原子性,即要么执行成功要么执行失败。不会出现数据不一致性问题。,默认情况下,数据库连接处于自动提交模式。每个SQL语句命令一旦被执行便被提交给数据库。一旦命令被提交,就无法对它进行回滚操作。 在Java中,可以使用下列步骤编写包含事务处理代码: 1)使用Connection对象的getAutoCommit方法获得当前自动提交模式值。 例如,使用下列语句关闭自动提交模式。 boo
28、lean transmode=conn.getAutoCommit(); conn.setAutoCommit(false);,2)编写事务处理代码 例如,执行多个更新语句: Statement stat = conn.createStatement();stat. executeUpdate(cmd1);stat. executeUpdate(cmd2);stat. executeUpdate(cmd3);,3)执行Connection对象的commit()方法mit(); conn.setAutoCommit(transmode); 如果发生错误,则调用:conn.rollback();此
29、时,程序将自动撤销自上次提交以来的所有命令。当事务被SQLException异常中断时,通常的办法是发起回滚操作。下面举例说明之.,【例7.10】 使用事务编写应用程序,程序运行结果?,本示例程序的功能: 将更新和查询语句构成一个事务。当所有语句都顺利执行之后,事务可以被提交。否则,如果其中某个语句遇到错误,那么事务将被回滚,就好像没有执行过任何命令一样。,小结- 编写JDBC应用程序的基本步骤,JDBC数据库应用开发基本步骤是: 加载驱动程序, 指定数据库URL,连接数据库, 编写SQL语句,创建SQL语句对象(如果是预备语句,还需绑定输入参数) 执行SQL语句, 若有返回结果,则操作结果集
30、, 关闭各级数据库对象。,练习题,下列关于驱动程序的说法错误的是( )A) JDBC-ODBC 桥驱动程序的java.sql.Driver 接口在sun.jdbc.odbc.JdbcOdbcDriver中实现。并且在JAVA_HOMEJREBIN 目录下有JdbcOdbc.dll 文件支持B) 同JDBC-ODBC 桥驱动程序相似,本地API部分Java驱动程序也需要在每个客户端机器上装载和操作系统相关的二进制码C) 使用JDBC-ODBC可以访问任意类型的数据库 D) JDBC直连模式由数据库厂商提供专用驱动程序库,包括MSSQL,Oracle,mySQL等产品在内,Answer to Qu
31、estion 1) ?,Question 1),Connection接口常用的方法包括( )A) Statement CreateStatement() B) PreparedStatement prepareStatement(String sql) C) CallableStatement prepareCall(String sql) D) B 和 C,Question 2),Answer to Question 2) ?,关于Statement的使用下列说法正确的是( )A) 继承于Statement的PreparedStatement接口也继承了它的executeQuery、exec
32、uteUpdate和execute方法B) Statement是预编译的,效率高C) Statement对象用Connection的方法createStatement创建D) Statement对象还可以绑定参数,防SQL注入问题,Answer to Question 3) ?,Question 3),有关Connection对象,以下说法正确的是( )A由DriverManager类的getConnection方法得到B由DataSource接口的getConnection方法得到C由第三方类的getConnection方法得到DA和B,Answer to Question 4) ?,Question 4),关于DriverManager类下列说法正确的是( )A) JDBC的应用层,作用于数据库和驱动程序之间B) 位于JDBC的管理层,跟踪可用的驱动程序C) 跟踪可用的用户程序D) 以上说法都不对,Question 5),Answer to Question 5) ?,本章小结,主要介绍了使用JDBC开发技术进行Java数据库应用开发的具体步骤和应用举例。介绍了JDBC的一些高级特性,包括:预备语句、可更新的和可滚动的记录集、元数据和事务,还有手动提交模式等。,