第7章JSP中使用数据库_第1页
第7章JSP中使用数据库_第2页
第7章JSP中使用数据库_第3页
第7章JSP中使用数据库_第4页
第7章JSP中使用数据库_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、3/6/20221Java Web开发技术开发技术第第7章章 JSP中使用数据库中使用数据库3/6/2022.27.1 JDBC技术概述 几乎所有的应用都要涉及到数据的保存。在很多系统中,数据库都是生命的核心,作为软件开发人员,必须懂得如何操作和维护数据库。 本章首先介绍JDBC的工作原理及其四种类型的驱动,随后探讨如何使用JDBC技术连接常用的数据库,如SQL Server,Access,Oracle等,并给出在JSP中使用数据库的具体例子。最后,介绍了数据库连接池的优点及工作原理并举例。 3/6/20 什么是 JDBC lJDBC是Java数据库连接(Java DataB

2、ase Connectivity)技术的简称 ,它是由JavaSoft公司(Sun公司负责开发Java产品的业务单位)同数据库及数据库工具厂家一起建立的独立于DBMS的机制。 JDBC是一种用于执行SQL语句的Java API。它由一组用Java编程语言编写的类和接口组成。这个API由java.sql.*和javax.sql.*两个包中的一些类和接口组成,它为数据库开发人员提供了一个标准的API,使他们能够用纯Java API 来编写数据库应用程序。 3/6/2022.4JDBC的优点的优点lJava具有坚固、安全、易于使用、易于理解和可从网络上自动下载 等优点;l可移植性强:不必为每一种数据

3、库编写不同的调用程序 ,只需用JDBC API编写一个程序就够了;3/6/20两层模型和三层模型 客户端 JDBC 数据库服务器 DBMS 相关协议 图 4-1 两层模型 web 服务器 JDBC 数据库服务器 DBMS 相关协议 图 4-2 三层模型 浏览器 HTTP,RMI,COBAR 调用 3/6/20 JDBC驱动程序的类型lJDBC-ODBC桥加ODBC驱动 l本地API驱动 lJDBC 网络纯Java驱动 l本地协议纯 Java 驱动 3/6/2022.7JDBC-ODBC桥加桥加ODBC驱动驱动l先把JDBC调用转化为ODBC调用,再利用ODB

4、C来与数据库交互 。l现存许多可用的ODBC驱动程序与大量数据库的交互,减少开发人员进行企业开发的麻烦 。 lODBC数据源需要提前在客户端进行注册,对于远程的客户端,操作极不方便,丢失平台无关性。 l适用于企业网或用Java编写的三层结构的应用程序 。3/6/2022.8本地本地API驱动驱动 l将标准的JDBC调用转变为对本地数据库原始驱动程序调用,再通过数据库的原始驱动程序与数据库交互。 l比JDBC-ODBC桥具有更优良的性能 。l丢失JDBC平台无关性的好处,而且也需要安装客户端的数据库原始驱动。 3/6/2022.9JDBC 网络纯网络纯Java驱动驱动 lJDBC网络驱动程序传送

5、JDBC命令到一个中间件上,这个中间件再将JDBC调用请求传送到数据库中,数据库返回的结果集也通过这个中间件来返回到应用程序。 l与平台无关的,并且不需要客户端的安装和管理,因此很适合于用做Internet的应用。 l必须处理Web所提出的安全性、通过防火墙的访问等方面的额外要求。3/6/2022.10本地协议纯本地协议纯 Java 驱动驱动 l直接访问数据库,中间不需要任何转换或通过其它任何的中间件就能完成交互 。l将成为从JDBC访问数据库的首选方法,因为他们提供了Java的所有优点。3/6/2022.11四种四种JDBC驱动程序原理比较驱动程序原理比较 客户端 本地 JAVA API 数

6、据库 服务器 客户端链接库 图 4-4 本地 API 驱动 中间层服务器 数据库 服务器 数据链接库 图4-5 网络纯Java驱动 网络协议驱动程序 客户机 客户端 JDBC-ODBC 桥 ODBC 驱动程序 数据库 服务器 客户端链接库 图 4-3 JDBC-ODBC 桥驱动 客户端 数据库 服务器 数据库驱动协议 图 4-6 本地协议纯 Java 驱动 3/6/2022.127.2 使用JDBCl要使用JDBC技术主要包括以下步骤:l注册和加载驱动器 ;l与数据库建立连接;l发送SQL语句;l处理结果;1.关闭连接;3/6/20 注册和加载驱动器l加载JDBC驱动是通过

7、调用方法java.lang.Class.forName(),下面列出常用的几种数据库驱动程序加载语句的形式 : lClass.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);/使用JDBC-ODBC桥驱动程序,事先必须在Windows中注册ODBC数据源 lClass.forName(“oracle.jdbc.driver.OracleDriver”);/使用Oracle的JDBC驱动程序 lClass.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);/使用SQL Server的JDBC驱动程序 l

8、Class.forName(“com.ibm.db2.jdbc.app.DB2Driver”);/使用DB2的JDBC驱动程序 lClass.forName(org.gjt.mm.mysql.Driver);/使用MySql的JDBC驱动程序 3/6/20 建立连接l与数据库建立连接的方法是调用DriverManager.getConnection(String url, String user, String password )方法。l下述代码显示如何打开一个与位于URL为jdbc:odbc:wombat 的数据库的连接。所用的用户标识符为oboy,口令为12Java:

9、 String url = jdbc:odbc:wombat;Connection con = DriverManager.getConnection(url, oboy, 12Java);3/6/2022.15几种数据库的连接语句的形式几种数据库的连接语句的形式 String url=jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=pubs;String user=sa;String password=“”;Connection conn= DriverManager.getConnection(url,user,password)

10、;String url=jdbc:db2:/localhost:5000/sample;String user=admin; String password=; Connection conn= DriverManager.getConnection(url,user,password); String url=jdbc:mysql:/localhost/softforum?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1; Connection conn= DriverManage

11、r.getConnection(url); Connection con=DriverManager.getConnection(“jdbc:oracle:oci8:db”,“scott”,“tiger”);/使用Oracle的JDBC OCI驱动程序 Connection con=DriverManager.getConnection(jdbc:oracle:thin:host:8080:db,scott,tiger);/使用Oracle的JDBC Thin驱动程序 3/6/20 发送SQL语句lStatement对象用于将 SQL 语句发送到数据库中。实际上有三种 St

12、atement对象:lStatement:用于执行不带参数的简单SQL语句;lPreparedStatement(从 Statement 继承):用于执行带或不带IN参数的预编译SQL语句;1. CallableStatement(从PreparedStatement 继承):用于执行数据库存储过程的调用。 3/6/20.1 创建Statement对象lStatement 对象用Connection的方法createStatement()创建。createStatement()的语法形式为: public Statement createStatement() throws

13、 SQLExceptionl如下列代码段中所示: Connection con = DriverManager.getConnection(url, sunny, );Statement stmt = con.createStatement(); 3/6/2022.18Statement接口中的主要方法接口中的主要方法 lResultSet executeQuery (String sql) /执行Statement对象,返回单个结果集lint executeUpdate (String sql) /执行Statement对象,返回本次操作影响的行数lboolean execute (Stri

14、ng sql) /执行Statement对象,返回布尔值lvoid close () /关闭Statement对象lint getMaxFieldSize () /获得字段最大长度lvoid setMaxFieldSize (int max) /设置字段最大长度lint getMaxRows () /获得最大行数lvoid setMaxRows (int max) /设置最大行数lint getQueryTimeout () /获得查询超时时间限lvoid setQueryTimeout (int seconds) /设定查询超时时间限ljava.sql.SQLWarning getWarni

15、ngs () /获得与statement对象有关的警告lResultSet getResultSet () /得到下一个结果集lint getUpdateCount () /得到修改的行数lboolean getMoreResults () /检测是否有多个结果集 3/6/20.2创建PreparedStatement对象l如果需要多次执行一个SQL语句,可以使用PreparedStatement对象。在创建PreparedStatement对象时,通过传递不同参数值多次执行PreparedStatement对象,可以得到多个不同的结果。 lPreparedStatemen

16、t对象用Connection的prepareStatement()方法创建。如: PreparedStatement pStmt = conn.prepareStatement(“insert into emp (empno , ename) values(?,?)”); 生成PreparedStatement对象的字符串中用“?”代表一个可以产生变化的IN型参数 3/6/2022.20PreparedStatement接口的主要方法接口的主要方法 lvoid clearParameters () /清除PreparedStatement对象中的参数lvoid setAsciiStream (

17、int parameterIndex, java.io.InputStream x, int length) lvoid setBinaryStream (int parameterIndex, java.io.InputStream x, int length) lvoid setBoolean (int parameterIndex, boolean x) lvoid setByte (int parameterIndex, byte x) lvoid setBytes (int parameterIndex, byte x) lvoid setDate (int parameterInd

18、ex, java.sql.Date x) lvoid setDouble (int parameterIndex, double x) lvoid setFloat (int parameterIndex, float x) lvoid setInt (int parameterIndex, int x) lvoid setLong (int parameterIndex, long x) lvoid setShort (int parameterIndex, short x) 3/6/2022.21PreparedStatement接口的主要方法(续)接口的主要方法(续)lvoid setS

19、tring (int parameterIndex, String x) lvoid setTime (int parameterIndex, java.sql.Time x) lvoid setTimestamp (int parameterIndex, java.sql.Timestamp x) lvoid setUnicodeStream (int parameterIndex, java.io.InputStream x, int length) lvoid setObject (int parameterIndex, Object x)lResultSet executeQuery

20、() /执行PreparedStatement对象,返回单结果集lint executeUpdate () /执行PreparedStatement对象,返回操作影响的行数lboolean execute () /执行PreparedStatement对象,返回布尔值3/6/2022.22PreparedStatement接口的方法说明接口的方法说明l其中的参数parameterIndex表示在构造PreparedStatement对象时”?”从左到右出现的位置,从1开始。l参数x表示给”?”设定的值。l究竟用哪一个setXXX()方法,由”?”所表示的参数类型来决定。l因为x的类型是java

21、.sql.Types中的类型,而参数的类型是某种数据库中的数据类型,因此应该保证它们的类型能够相对应。一般来说,它们有下面的对应关系如下表所示:3/6/2022.23数据库数据类型和数据库数据类型和Java数据类型的对应关系数据类型的对应关系 3/6/2022.24使用使用PreparedStatement 举例举例st=con.prepareStatement(insert into EMP(EMPNO,ENAME) values (?,?);st.setInt(1,7777);st.setString(2,Adam);3/6/2022.2创建CallableStatemen

22、t对象lCallableStatement对象为数据库提供了一种以标准形式调用储存过程的方法。CallableStatement由Connection对象的方法prepareCall()创建。其中的参数sql形式为:? = call , . call前面的”?”表示过程返回结果参数。方括号指示其中的内容是可选的。它们不是语法的必要部分。l如:CallableStatement cStmt = conn.prepareCall(call showEmployees(?,?); 3/6/2022.26CallableStatement接口中的主要方法接口中的主要方法 lbyte getByte(i

23、nt parameterIndex) l/返回序号为parameterIndex参数的字节值,参数类型为JDBC TINYINTlDate getDate(int parameterIndex)l/返回序号为parameterIndex参数的值,参数值的类型为java.sql.Dateldouble getDouble(int parameterIndex) /返回序号为parameterIndex参数的double类型值lfloat getFloat(int parameterIndex) /返回序号为parameterIndex参数的float类型值lint getInt(int para

24、meterIndex) /返回序号为parameterIndex参数的int类型值lString getString(int parameterIndex) /返回序号为parameterIndex参数的String类型值lvoid registerOutParameter(int parameterIndex, int sqlType) l/将序号为parameterIndex的参数注册为JDBC中的数据类型lvoid setDouble(String parameterName, double x)l / 设置参数parameterName为double类型值xlvoid setFloat

25、(String parameterName, float x) / 设置参数parameterName为float类型值xlvoid setInt(String parameterName, int x) / 设置参数parameterName为int类型值x3/6/2022.27方法说明方法说明l这里的parameterIndex、x和sqlType的意义同prepareStatement中的说明。l在创建CallableStatement对象前应检查所用的数据库是否支持存储过程,可以使用DatabaseMetaData对象的supportsStoredProcedures()方法,其语法形

26、式为:public boolean supportsStoredProcedures() throws SQLExceptionl究竟”?”表示IN型参数还是表示OUT型参数,取决于存储过程定义。l使用CallableStatement对象的过程为:创建CallableStatement对象、使用registerOutParameter()方法注册登记OUT参数、使用setXXX()方法设置IN参数实际值、使用execute()方法执行该存储过程、使用getXXX()方法取得OUT参数返回值。3/6/2022.28使用使用CallableStatement举例举例 l先建立一个存储过程: cr

27、eate or replace procedure show(name out varchar2,num in number) as begin Select Ename into name from emp where empno=num; end;l然后使用CallableStatement对象: CallableStatement cs=con.prepareCall(call show(?,?); cs.registerOutParameter(1,java.sql.Types.CHAR); cs.setInt(2,7777); cs.execute(); String str=cs.

28、getString(1); 3/6/2022.297.2.4使用Statement 对象执行语句l创建了Statement对象 ,完成了SQL语句发送后,就要调用Statement对象中的方法执行该SQL语句,进而得到执行的结果。 lStatement接口提供了三种执行SQL语句的方法:executeQuery()、executeUpdate()和execute()。它们的语法形式分别为:3/6/2022.30三种执行三种执行SQL语句的方法语句的方法lexecuteQuery()返回语句执行后的单个结果集的,所以通常用于SELECT语句 lexecuteUpdate()返回值是一个整数,指示

29、受影响的行数(即更新计数)。lexecute()返回一个boolean值,execute()方法执行后可以得到多个结果集、多个更新计数或二者的组合。本章后面将在单独一节中对其进行介绍。3/6/2022.317.2.5 ResultSet对象 lResultSet对象l行和游标l 数据类型和转换l对非常大的值使用流lNULL结果值3/6/2022.3ResultSet对象lResultSet对象是executeQuery()方法的返回值,它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXX

30、X方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。lResultSet里的数据一行一行排列,每行有多个字段,并且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSet的next()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环。 3/6/2022.3行和游标lResultSet对象自动维护指向当前数据行的游标。每调用一次next()方法,游标向下移动一行。 l在SQL中,结果集的游标是有名字的。可通过调用ResultSet对象的getCurso

31、rName()获得游标名。 l有时候需要结果集的游标前后移动,这是可滚动结果集。为了获得滚动结果集,必须先用下面方法得到一个Statement对象:Statement st=con.createStatement(int type, int concurrency);根据type和concurrency的取值,当执行ResultSet r=st.executeQuery()时,会返回不同类型的结果集。l 结果集滚动的方法很多,详见课本本章节。3/6/2022.3 数据类型和转换l对于getXXX()方法,JDBC驱动程序试图将基本数据转换成指定Java类型,然后返回适合的Jav

32、a值。例如,如果为getString()方法,而数据库中数据类型为 VARCHAR,则JDBC驱动程序将把VARCHAR转换成Java String。GetString()的返回值将为Java String 对象。再如,除了getBytes()和getBinaryStream()之外的任何getXXX()方法都可用来获取LONGVARCHAR值,但是推荐根据返回的数据类型使用getAsciiStream()或 getUnicodeStream()方法。方法getObject()将任何数据类型返回为Java Object。 3/6/2022.3对非常大的值使用流lResultSe

33、t可以获取任意大的LONGVARBINARY或LONGVARCHAR数据。方法之一是通过让ResultSet类返回java.io.InputStream来完成。lJDBC API具有三个获取流的方法,分别具有不同的返回值: getBinaryStream():返回只提供数据库字节而不进行任何转换的流。getAsciiStream():返回提供单字节ASCII字符的流。getUnicodeStream():返回提供双字节Unicode字符的流。 3/6/2022.3NULL结果值l要确定给定结果值是否是JDBC NULL,必须先读取该列,然后使用ResultSet的wasNull

34、()方法检查该次读取是否返回JDBC NULL。l方法wasNull()将返回下列值之一: (1)Java null值:对于返回Java对象的getXXX()方法(例如 getString()、getDate()、getTime()、getTimestamp()、getAsciiStream()、getUnicodeStream()、getBinaryStream()、getObject()等)。 (2)0值:对于 getByte()、getShort()、getInt()、getLong()、getFloat() 和 getDouble()。 (3)false 值:对于 getBoolean

35、()。3/6/2022.3可选结果集或多结果集l但有些情况下,应用程序在执行语句之前不知道该语句是否返回结果集。此外,有些已存储过程可能返回几个不同的结果集和/或更新计数。 JDBC提供了一种机制,允许应用程序处理由结果集和更新计数组成的任意集合。l这种机制的原理是:首先调用一个完全通用的execute()方法,然后调用getResultSet()、getUpdateCount()和getMoreResults()三个方法。 3/6/2022.38可选结果集或多结果集可选结果集或多结果集 (续)(续)下面的代码演示了一种方法用来确认已访问方法execute()所产生的全部结果集

36、和更新计数:stmt.execute();while (true) int rowCount = stmt.getUpdateCount();if (rowCount 0) / 它是更新计数System.out.println(Rows changed = + count);stmt.getMoreResults();continue;if (rowCount = 0) / DDL 命令或 0 个更新System.out.println( No rows changed or statement was DDL command);stmt.getMoreResults();continue;/

37、 执行到这里,证明有一个结果集/ 或没有其它结果ResultSet rs = stmt.getResultSet();if (rs != null) . . . / 使用元数据获得关于结果集列的信息stmt.getMoreResults();lelsebreak; / 没有其它结果3/6/2022.397.2.6 关闭 Statement对象和Connection对象l作为一种好的编程风格,应在不需要Statement对象和Connection对象时显式地关闭它们。关闭Statement对象和Connection对象的语法形式为: public void close() throws SQLE

38、xceptionl用户不必关闭ResultSet。当它的 Statement 关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被自动关闭。l例:Employee.java,EmployeePrepStat.java3/6/2022.407.2.7 事务l事务是由具有“原子性”的一个或多个语句,即这些语句要么全部被执行、完成并被提交,要么全部还原。当调用连接的提交方法commit()或回滚方法rollback()时,当前事务即告结束,另一个事务随即开始。l缺省情况下,新连接将处于自动提交模式。也就是说,当执行完语句后,将自动对那个语句调用commit()方法。这种情况下

39、,一个事务只由一个语句组成。如果禁用自动提交模式,事务将要等到commit()或rollback()方法被显式调用时才结束,因此它将包括上一次调用commit()或rollback()方法以来所有执行过的语句。对于第二种情况,事务中的所有语句将作为组来提交或还原。 l例:SimpledbBatch.java3/6/2022.417.3 在JSP中通过JDBC-ODBC桥使用数据库l无论访问什么数据库,使用JDBC-ODBC桥的方法完全一样,即先注册32位数据源,再按照上节中的步骤(注册和加载驱动器、与数据库建立连接、发送SQL语句和处理结果)使用数据库。 l本节图4-9到图4-16演示了如何注

40、册数据源的全过程。3/6/2022.427.3.1 查询举例l顺序查询(例example4_1.jsp,example4_2.jsp )l 随机查询(例example4_3.jsp ,example4_4.jsp )l 参数查询(例example4_5.jsp ,bynename.jsp , byscore.jsp )l 排序查询(例example4_6.jsp ,byname1.jsp )3/6/2022.437.3.2 更新记录举例l例example4_8.jsp输入学生姓名和各科成绩,并将请求提交给newResult.jsp,该页面实现更新记录。运行结果下图所示。3/6/2022.447.3.3 添加记录举例

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论