WEB应用与开发_10JDBC与数据库(JDBC与SQL语句、存储过程的应用)_第1页
WEB应用与开发_10JDBC与数据库(JDBC与SQL语句、存储过程的应用)_第2页
WEB应用与开发_10JDBC与数据库(JDBC与SQL语句、存储过程的应用)_第3页
WEB应用与开发_10JDBC与数据库(JDBC与SQL语句、存储过程的应用)_第4页
WEB应用与开发_10JDBC与数据库(JDBC与SQL语句、存储过程的应用)_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

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

文档简介

1、课题课题JDBC与数据库(与数据库(JDBC与与SQL语句、存语句、存储过程的应用)储过程的应用) 目的要求目的要求 掌握掌握JDBC存取各种不同数据库的方法存取各种不同数据库的方法 教学重点掌握教学重点掌握JDBC与不同数据库的连接字符串、与不同数据库的连接字符串、连接池连接池教学难点教学难点 JSP如何存取存储过程中输入参数、输出如何存取存储过程中输入参数、输出参数、输入输出参数、输入输出参数参数教学课时教学课时 4(含(含2课时上机)课时上机)教学方法教学方法 讲解、示例与启发式教学相结合讲解、示例与启发式教学相结合教学内容和步骤教学内容和步骤10.1 JDBC与数据库编程与数据库编程1

2、0.1.1 JDBC的的Driver可分为以下四种类型可分为以下四种类型(1)JDBC-ODBC Bridge和和ODBC Driver这种驱动器器通过这种驱动器器通过ODBC驱动器提供数据库连接。使用这驱动器提供数据库连接。使用这种驱动器,要求每一台客户机都装入种驱动器,要求每一台客户机都装入ODBC的驱动器。的驱动器。(2)Native-API partly-Java Driver这种驱动器将这种驱动器将JDBC指令转化成所连接使用的指令转化成所连接使用的DBMS的操的操作形式。各客户机使用的数据库可能是作形式。各客户机使用的数据库可能是Oracle,可能是,可能是Sybase,也可能是,

3、也可能是Access,都需要在客户机上装有相应,都需要在客户机上装有相应DBMS的驱动程序。的驱动程序。(3)JDBC-Net All-Java Driver这种驱动器将这种驱动器将JDBC指令转化成独立于指令转化成独立于DBMS的的网络协议形式,再由服务器转化为特定网络协议形式,再由服务器转化为特定DBMS的协的协议形式。有关议形式。有关DBMS的协议由各数据库厂商决定。的协议由各数据库厂商决定。这种驱动器可以联接到不同的数据库上,最为灵活。这种驱动器可以联接到不同的数据库上,最为灵活。目前一些厂商已经开始添加目前一些厂商已经开始添加JDBC的这种驱动器到他的这种驱动器到他们已有的数据库中介

4、产品中。要注意的是,为了支们已有的数据库中介产品中。要注意的是,为了支持广域网存取,需要增加有关安全性的措施,如防持广域网存取,需要增加有关安全性的措施,如防火墙等等。火墙等等。(4)Native-protocol All-Java Driver这种驱动器将这种驱动器将JDBC指令转化成网络协议指令转化成网络协议后不再转换,由后不再转换,由DBMS直接使用。相当于客户机直直接使用。相当于客户机直接与服务器联系,对局域网适用。接与服务器联系,对局域网适用。 在这四种驱动器中,后两类在这四种驱动器中,后两类“纯纯Java”(All-Java)的驱动器效率更高,也更具有通用性。但目的驱动器效率更高,

5、也更具有通用性。但目前第一、第二类驱动器比较容易获得,使用也较普前第一、第二类驱动器比较容易获得,使用也较普遍。遍。10.1.2 关于关于JDBC Url语法如下:语法如下: jdbc:-驱动程序名称或数据库连接机制,子协议名驱动程序名称或数据库连接机制,子协议名称的典型例子就是称的典型例子就是ODBC ,如:如:jdbc:odbc:fff-一种标识数据库的方法。子名称可以依据不一种标识数据库的方法。子名称可以依据不同的子协议而发生变化同的子协议而发生变化如:如:jdbc:dbnet/womat:356/fff ODBC子协议子协议:Jdbc:odbc:;=如:如: jdbc:odbc:sql

6、conn:UID=sa;PWD=ww10.2 JDBC编程编程10.2.1 程序基本结构程序基本结构 一般的一般的JDBC程序都完成三项功能:与数据库建立连接;程序都完成三项功能:与数据库建立连接;传送传送SQL 声明以及对返回结果进行处理。下面我们通过声明以及对返回结果进行处理。下面我们通过一个具体例子说明这三项功能的实现过程。一个具体例子说明这三项功能的实现过程。例例1: Creage.java给出了一个简单的给出了一个简单的JDBC程序,此程序程序,此程序执行后创建一张名为执行后创建一张名为testTable的表,表中包括两个域,的表,表中包括两个域,域名分别为域名分别为id和和name

7、。import .URL;import java.sql.*;class Createpublic static void main (String args)String url=jdbc:odbc:demo;String query=CREATE TABLE testTable + (id INT,name CHAR(10); try/下载下载jdbc-odbc bridge 驱动器驱动器 Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);/关于此句参见下面关于此句参见下面Cyclone的注释的注释/与驱动器建立连接与驱动器建立连接 ,这里可使用不同的

8、特定驱动,如这里可使用不同的特定驱动,如jdbcfororacle或或jdbcforsqlserverConnection con=DriverManager.getConnection(url,user,password);/创建一个创建一个Statement对象对象Statement stmt=con.createStatement();/执行执行SQL声明声明stmt.executeUpdate(query);System.out.println(Create successfully!); /关闭关闭 stmstmt.close();/关闭连接关闭连接con.close();catch

9、(SQLException ex)/SQL异常信息异常信息System.out.println(n*SQLException caught *n);while(ex!=null)System.out.println(SQLState:+ex.getSQLState();System.out.println(Message:+ex.getMessage();System.out.println(Vendor:+ex.getErrorCode();ex=ex.getNextException();System.out.println();catch(java.lang.Exception ex)e

10、x.printStackTrace();22 Statement类及其子类类及其子类1)Statement接口接口Statement stmt=con.createStatement();/执行执行SQL声明声明int count1=stmt.executeUpdate(INSERT INTO testTable(id,name) VALUES(1,wu);int count2=stmt.executeUpdate(INSERT INTO testTable(id,name) VALUES(2,wang);2)PreparedStatement接口接口String data=5,xu,6,ya

11、n;PreparedStatement pstmt=con.prepareStatement(INSERT INTO testTable (id,name) VALUES(?,?);/参数赋值,执行参数赋值,执行SQL声明声明for (int i=0;idata.length;i+) pstmt.setInt(1,Integer.parseInt(datai0); pstmt.setString(2,datai1); pstmt.executeUpdate(); 3)CallableStatement接口接口 CallableStatement cstmt=con.prepareCall(ca

12、ll Search(?);/参数赋值参数赋值cstmt.setInt(1,934678);/执行储存过程。执行储存过程。cstmt.execute();2.3 结果集结果集ResultSet及及ResultSetMetaDataString query = SELECT * FROM testTable;Statement stmt=con.createStatement();/发出查询要求,获得结果集发出查询要求,获得结果集ResultSet rs=stmt.executeQuery(query);/显示结果集各行各列显示结果集各行各列System.out.println(The detai

13、l of testTable is:);ResultSetMetaData rsmd=rs.getMetaData();/获得结果集列数获得结果集列数in numCols=rsmd.getColumnCount();/显示列标题显示列标题for(int i=1;i1) System.out.print(,);System.out.print(rsmd.getColumnLabel(i);System.out.println();/显示结果集信息显示结果集信息while(rs.next()/显示一行显示一行for(int i=1;i1) System.out.print(,);System.ou

14、t.print(rs.getString(i);2.4 DatabaseMetaDataDatabaseMetaData dma = con.getMetaData();/驱动器和驱动器和URL信息信息System.out.println(nConnected to + dma.getURL();System.out.println(Driver + dma.getDriverName();System.out.println(Version + dma.getDriverVersion() /数据库信息数据库信息System.out.println(nDataBase name: + dma

15、.getDatabaseProductName()+dma.getDatabaseProductVersion();System.out.println(DataBase supports SQL keywords:nt + dma.getSQLKeywords();/数据库功能信息函数数据库功能信息函数dma.supportsANSI92EntryLevelSQL()dma.supportsANSI92FullSQL()dma.supportsStoredProcedures()10.2.2 JDBC数据类型及类型转换数据类型及类型转换 JDBC的数据类型的数据类型JDBC的的sql包中除了

16、与数据库连接有关的包中除了与数据库连接有关的抽象接口及与驱动器有关的抽象接口及与驱动器有关的DriverManager、DriverPropertyInfo等类型外,还定义了若干数等类型外,还定义了若干数据类,用以代表数据库中可能用到的据类,用以代表数据库中可能用到的SQL类型。类型。下面我们就对它们逐一进行简略介绍。下面我们就对它们逐一进行简略介绍。 sql.Datesql包中的日期类包中的日期类Date是是util包中包中Date类的子类的子类,实际上也是类,实际上也是util.Date类的子集。它只处理年月类的子集。它只处理年月日,而忽略小时和分秒,用以代表日,而忽略小时和分秒,用以代表

17、SQL的的DATE信息。信息。Date类的构造方法为:类的构造方法为:public Date(int year, int mouth, int day)其中参数格式同其中参数格式同util.Date类的构造方法一样,年类的构造方法一样,年参数为所需设定的年份减去参数为所需设定的年份减去1900所得的整数值,月所得的整数值,月参数为参数为0至至11,日参数为,日参数为1至至31。如。如1998年年1月月23日日所对应创建日期类的方法调用为:所对应创建日期类的方法调用为:Date d=new Date(98,0,23);Date类还提供两个与类还提供两个与String类互类互相转换的方法,分别是:

18、相转换的方法,分别是:public static Date valueOf(String s)将字符串类参数转换为日期类对象。将字符串类参数转换为日期类对象。其中其中String类参数类参数S的格式为的格式为“年年-月月-日日”,加加“1997-04-12”。public String toString()将日期类对象转换为将日期类对象转换为String类对象表类对象表示,同样采用示,同样采用“年年-月月-日日”的格式。的格式。 sql.Time 该类是该类是util.Date类的子类,也是它的一个子集。类的子类,也是它的一个子集。在在Time类里,只处理小时和分秒,代表类里,只处理小时和分秒

19、,代表SQL的的TIME类型。它与类型。它与sql.Date合起来才表示完整的合起来才表示完整的util.Date类类信息。信息。 Time类的构造方法为:类的构造方法为: public Time(int hour,int minute,int second)其中小时参数值为其中小时参数值为0至至23,分秒参数取值均为,分秒参数取值均为0至至59。 与与sql.Date一样,一样,Time类也定义了两个与类也定义了两个与String类互相转换的函数类互相转换的函数ValueOf和和String。不同的。不同的是是String类对象的格式为类对象的格式为“小时:分:秒小时:分:秒”,如,如“12

20、:26:06”。 sql.Timestamp 这个类也是这个类也是util.Date类的子类,其中除了包含年月日、类的子类,其中除了包含年月日、小时和分秒和信息之外,还加入了纳秒信息小时和分秒和信息之外,还加入了纳秒信息(nanosecond),1纳秒即纳秒即1毫微秒。毫微秒。Timestamp类用来代表类用来代表SQL时间戳时间戳(Timestamp)类型信息。类型信息。Timestamp类的构造方法为:类的构造方法为:public Timestamp(int year, int mouth, int date, int hour, int minute, int second, int n

21、ano)其中纳秒参数的取其中纳秒参数的取值从值从0至至999,999,999,其余各参数同前。,其余各参数同前。Timestamp类特别定义了设置和获得纳秒信息的方法,类特别定义了设置和获得纳秒信息的方法,分别是分别是public getnanos()获取时间戳的纳秒部分获取时间戳的纳秒部分public void setNanos(int n)以给定数值设置时间戳的纳秒部分以给定数值设置时间戳的纳秒部分 sql.TypesTypes类是类是Object类的直接子类。在这个类类的直接子类。在这个类中以静态常量的形式定义了可使用的中以静态常量的形式定义了可使用的SQL的数值的数值类型。所有这些类型

22、常量都以前缀类型。所有这些类型常量都以前缀public final static int的形式标明是公有静态的形式标明是公有静态整数,且不可改动。具体的类型名和含义如表整数,且不可改动。具体的类型名和含义如表11.1所示。其中所示。其中OTHER用来代表数据库定义的特用来代表数据库定义的特殊数据,可以用殊数据,可以用getObject或或setObject方法将其方法将其映射为一个映射为一个Java的的Object对象。对象。表表 1 Types中定义的中定义的SQL类型类型 类型名含义BIBIGIGINTNT长整型数BINARY二进制数BIT比特数CHAR字符型DATE日期型DECIMAL十

23、进制数DOUBLE双精度数FLOAT浮点数INTEGER整数LONGVARBINARY可变长型二进制数LONGVARCHAR可变长型字符NULL空类型NUMERIC数值型OTHER其他类型REAL实数SMALLINT短整型TIME时间类型TIMESTAMP时间戳类型TINYINT微整型VARBINARY可变二进制数VARCHAR可变字符型 SQL与与Java由于由于SQL数据类型与数据类型与Java的数据类型不一致,的数据类型不一致,因而在使用因而在使用Java类型的应用程序与使用类型的应用程序与使用SQL类型的数类型的数据库之间,需要某种读写类型转换机制。实际上我们据库之间,需要某种读写类型

24、转换机制。实际上我们前面介绍的前面介绍的ResultSet类的类的“get”系列方法,系列方法,Statement及其子类的及其子类的“set“系列方法和系列方法和registerOutParameter方法,都是这一转换机制的组方法,都是这一转换机制的组成部分。成部分。需要进行的读写转换包括下面情况:需要进行的读写转换包括下面情况:从数据库中读取数值后,存放在从数据库中读取数值后,存放在ResultSet对对象中的是象中的是SQL类型的数据。而调用类型的数据。而调用“get”系列方法时,系列方法时,JDBC才将才将SQL类型转换为指定的类型转换为指定的Java类型。在一般类型。在一般情形下,

25、情形下,SQL类型相对应的类型相对应的Java类型如表类型如表11-2所示。所示。 SQL与与Java由于由于SQL数据类型与数据类型与Java的数据类型不一致,的数据类型不一致,因而在使用因而在使用Java类型的应用程序与使用类型的应用程序与使用SQL类型的数据类型的数据库之间,需要某种读写类型转换机制。实际上我们前面库之间,需要某种读写类型转换机制。实际上我们前面介绍的介绍的ResultSet类的类的“get”系列方法,系列方法,Statement及其及其子类的子类的“set“系列方法和系列方法和registerOutParameter方法,方法,都是这一转换机制的组成部分。都是这一转换机

26、制的组成部分。需要进行的读写转换包括下面情况:需要进行的读写转换包括下面情况:从数据库中读取数值后,存放在从数据库中读取数值后,存放在ResultSet对象对象中的是中的是SQL类型的数据。而调用类型的数据。而调用“get”系列方法时,系列方法时,JDBC才将才将SQL类型转换为指定的类型转换为指定的Java类型。在一般情类型。在一般情形下,形下,SQL类型相对应的类型相对应的Java类型如表类型如表11-2所示。所示。表表2 SQL类型一般所对应的类型一般所对应的Java类型类型SQL typeJava typeCHARjava.lang.StringVARCHARjava.lang.Str

27、ingLONGVARCHARjava.lang.StringNUMERICjava.lang.BignumDECIMALjava.lang.Bignum 字符类型字符类型JDBC JDBC 字符串数据类型为字符串数据类型为 CHARCHAR、VARCHAR VARCHAR 和和 LONGVARCHARLONGVARCHAR。类型类型 说明说明 Fixed-lengthSQL Server charchar 和 ncharnchar 数据类型直接映射到 JDBC CHARCHAR 类型。这些都是在列具有 SET ANSI_PADDING ON 的情况下,具有由服务器提供的填充的固定长度的类型。对

28、于 ncharnchar,填充始终是打开的,但对于 charchar,在未填充服务器字符列的情况下,JDBC 驱动程序将添加填充。Variable-lengthSQL Server varchar SQL Server varchar 和和 nvarchar nvarchar 类型直接映射到类型直接映射到 JDBC VARCHAR JDBC VARCHAR 类类型。型。LongSQL Server text SQL Server text 和和 ntext ntext 类型类型映射到映射到 JDBC LONGVARCHAR JDBC LONGVARCHAR 类型。类型。对于对于 SQL Ser

29、ver 2005 SQL Server 2005 来说,这来说,这些类型已过时,因此应改用大值类些类型已过时,因此应改用大值类型。型。针对针对 text text 和和 ntext ntext 服务器列使服务器列使用用 update update 和和 updateObject (int, updateObject (int, java.lang.Object)java.lang.Object) 方法时将失败方法时将失败。然而,对于。然而,对于 text text 和和 ntext ntext 服服务器列,支持将务器列,支持将 setObjectsetObject 方法方法用于指定的字符转换类

30、型。用于指定的字符转换类型。 二进制字符串类型二进制字符串类型JDBC 二进制字符串类型为二进制字符串类型为 BINARY、VARBINARY 和和 LONGVARBINARY。类型类型 说明说明 固定长度固定长度SQL Server binary SQL Server binary 类型直接映射类型直接映射到到 JDBC BINARY JDBC BINARY 类型。这是在列具类型。这是在列具有有 SET ANSI_PADDING ON SET ANSI_PADDING ON 的情况下,的情况下,具有由服务器提供填充的固定长度具有由服务器提供填充的固定长度类型。没有填充服务器类型。没有填充服务

31、器 char char 列时,列时,JDBC JDBC 驱动程序会添加填充。驱动程序会添加填充。SQL Server timestamp SQL Server timestamp 类型是具有类型是具有 8 8 个字节的固定长度的个字节的固定长度的 JDBC JDBC BINARY BINARY 类型。类型。可变长度可变长度SQL Server varbinary SQL Server varbinary 类型映射到类型映射到 JDBC VARBINARY JDBC VARBINARY 类型。类型。LongLongSQL Server image SQL Server image 类型映射到类型

32、映射到 JDBC LONGVARBINARY JDBC LONGVARBINARY 类型。对于类型。对于 SQL Server 2005 SQL Server 2005 来说,该类型已来说,该类型已过时,因此应改用大值类型。过时,因此应改用大值类型。SQL Server 2005 SQL Server 2005 中的中的 udt udt 类型作类型作为为 LONGBINARY LONGBINARY 类型映射到类型映射到 JDBCJDBC。 精确数字类型精确数字类型JDBC JDBC 精确数字类型直接映射到其对应的精确数字类型直接映射到其对应的 SQL ServerSQL Server 类型。类

33、型类型 说明说明 BITBITJDBC BIT JDBC BIT 类型表示可能是类型表示可能是 0 0 或或 1 1 的单个位。此类型映射到的单个位。此类型映射到 SQL SQL Server bit Server bit 类型。类型。TINYINTTINYINTJDBC TINYINT JDBC TINYINT 类型表示单个类型表示单个字节。此类型映射到字节。此类型映射到 SQL SQL Server tinyint Server tinyint 类型。类型。SMALLINTSMALLINTJDBC SMALLINT JDBC SMALLINT 类型表示有符类型表示有符号的号的 16 16

34、位整数。此类型映射位整数。此类型映射到到 SQL Server smallint SQL Server smallint 类类型。型。INTEGERINTEGERJDBC INTEGER JDBC INTEGER 类型表示有符号的类型表示有符号的 32 32 位整数。此类型映射到位整数。此类型映射到 SQL SQL Server int Server int 类型。类型。BIGINTBIGINTJDBC BIGINT JDBC BIGINT 类型表示有符号的类型表示有符号的 64 64 位整数。此类型映射到位整数。此类型映射到 SQL SQL Server bigint Server bigi

35、nt 类型。类型。NUMERICNUMERICJDBC NUMERIC JDBC NUMERIC 类型表示固定精度类型表示固定精度的十进制值,它可存放相同精度的的十进制值,它可存放相同精度的值。值。NUMERIC NUMERIC 类型映射到类型映射到 SQL SQL Server numeric Server numeric 类型。类型。DECIMALDECIMALJDBC DECIMAL JDBC DECIMAL 类型表示固定精度类型表示固定精度的十进制值,它可存放至少具有指的十进制值,它可存放至少具有指定精度的值。定精度的值。DECIMAL DECIMAL 类型映射到类型映射到 SQL S

36、erver decimal SQL Server decimal 类型。类型。JDBC DECIMAL JDBC DECIMAL 类型还映射到类型还映射到 SQL SQL Server money Server money 和和 smallmoney smallmoney 类类型,这些类型是特定的固定精度的型,这些类型是特定的固定精度的十进制类型,分别以十进制类型,分别以 8 8 个字节和个字节和 4 4 个字节进行存储。个字节进行存储。 近似数字类型JDBC 近似数值数据类型为 REAL、DOUBLE 和 FLOAT。类型类型 说明说明 REALJDBC REALREAL 类型具有 7 位精

37、度(单精度)并直接映射到 SQL Server realreal 类型。DOUBLEJDBC DOUBLE JDBC DOUBLE 类型具有类型具有 15 15 位精位精度(双精度)并直接映射到度(双精度)并直接映射到 SQL SQL Server float Server float 类型。类型。JDBC JDBC FLOAT FLOAT 类型是类型是 DOUBLE DOUBLE 的同义词。的同义词。由于由于 FLOAT FLOAT 与与 DOUBLE DOUBLE 之间可之间可能存在冲突,因此能存在冲突,因此 DOUBLE DOUBLE 为首为首选类型。选类型。 日期时间类型日期时间类型J

38、DBC TIMESTAMP 类型映射到类型映射到 SQL Server datetime 和和 smalldatetime 类型。类型。datetime 类型以两个类型以两个 4 字节整数进行存储。字节整数进行存储。smalldatetime 类型可存放相同的信息(日期类型可存放相同的信息(日期和时间),但精度较低,为两个和时间),但精度较低,为两个 2 字节的小整字节的小整数。数。10.3 JDBC与数据库的连接字符串与数据库的连接字符串 MySQL(http:/)mm.mysql-2.0.2-bin.jar Class.forName( org.gjt.mm.mysql.Driver );

39、 cn= DriverManager.getConnection( jdbc:mysql:/MyDbComputerNameOrIP:3306/myDatabaseName, sUsr, sPwd ); Oracle(http:/ Class.forName( oracle.jdbc.driver.OracleDriver ); cn= DriverManager.getConnection( jdbc:oracle:thin:MyDbComputerNameOrIP:1521:ORCL, sUsr, sPwd ); Sybase(http:/)jconn2.jar Class.forName

40、( com.sybase.jdbc.SybDriver ); cn = DriverManager.getConnection( jdbc:sybase:Tds:MyDbComputerNameOrIP:2638, sUsr, sPwd ); /(Default-Username/Password: dba/sql) Microsoft SQLServer(http:/) Class.forName( com.microsoft.jdbc.sqlserver.SQLServerDriver ); cn= DriverManager.getConnection( jdbc:microsoft:s

41、qlserver:/MyDbComputerNameOrIP:1433;databaseName=master, sUsr, sPwd ); ODBC Class.forName( sun.jdbc.odbc.JdbcOdbcDriver ); Connection cn = DriverManager.getConnection( jdbc:odbc: + sDsn, sUsr, sPwd ); informix Class.forName(rmix.jdbc.IfxDriver).newInstance(); String url =jdbc:informix-sqli:/

42、9:1533/testDB:INFORMIXSERVER=myserver; user=testuser;password=testpassword; sybaseClass.forName( com.sybase.jdbc.SybDriver ) url=jdbc:sybase:Tds::2638/asademo; SybConnection connection= (SybConnection)DriverManager.getConnection(url,dba,sql); 例例2: queryBook.jsp图书信息浏览图书信息浏览ID号号 书名

43、书名 出版社出版社 价格价格%Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver).newInstance();Connection con=java.sql.DriverManager.getConnection(jdbc:microsoft:sqlserver:/:1433;DatabaseName=jspdb,sa,);Statement stmt=con.createStatement();ResultSet rst=stmt.executeQuery(select * from book;);whil

44、e(rst.next()out.println();out.println(+rst.getString(bkld)+);out.println(+rst.getString(bkName)+);out.println(+rst.getString(bkPublisher)+);out.println(+rst.getFloat(bkPrice)+元元+);out.println();rst.close();stmt.close();con.close();%10.4 连接池连接池 连接池原理连接池原理 连接池连接池技术的核心思想是:连接复用,通过技术的核心思想是:连接复用,通过建立一个数据库

45、连接池以及一套连接使用、分配、建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭安全的复用,避免了数据库连接频繁建立、关闭的开销。另外,由于对的开销。另外,由于对JDBC中的原始连接进行中的原始连接进行了封装,从而方便了数据库应用对于连接的使用了封装,从而方便了数据库应用对于连接的使用(特别是对于事务处理),提高了开发效率,也(特别是对于事务处理),提高了开发效率,也正是因为这个封装层的存在,隔离了应用的本身正是因为这个封装层的存在,隔离了应用的本身的处理逻辑和具体数据库

46、访问逻辑,使应用本身的处理逻辑和具体数据库访问逻辑,使应用本身的复用成为可能。连接池主要由三部分组成:连的复用成为可能。连接池主要由三部分组成:连接池的建立、连接池中连接的使用管理、连接池接池的建立、连接池中连接的使用管理、连接池的关闭。的关闭。 连接池的管理连接池的管理 连接池管理策略是连接池机制的核心。当连接池建连接池管理策略是连接池机制的核心。当连接池建立后,如何对连接池中的连接进行管理,解决好连接立后,如何对连接池中的连接进行管理,解决好连接池内连接的分配和释放,对系统的性能有很大的影响。池内连接的分配和释放,对系统的性能有很大的影响。连接的合理分配、释放可提高连接的复用,降低了系连接

47、的合理分配、释放可提高连接的复用,降低了系统建立新连接的开销,同时也加速了用户的访问速度。统建立新连接的开销,同时也加速了用户的访问速度。下面介绍连接池中连接的分配、释放策略。下面介绍连接池中连接的分配、释放策略。 连接池的分配、释放策略对于有效复用连接池的分配、释放策略对于有效复用连接非常重要,我们采用的方法是一个很连接非常重要,我们采用的方法是一个很有名的设计模式:有名的设计模式:Reference Counting(引用记数)。该模式在复用资源方面应(引用记数)。该模式在复用资源方面应用的非常广泛,把该方法运用到对于连接用的非常广泛,把该方法运用到对于连接的分配释放上,为每一个数据库连接

48、,保的分配释放上,为每一个数据库连接,保留一个引用记数,用来记录该连接的使用留一个引用记数,用来记录该连接的使用者的个数。具体的实现方法是:者的个数。具体的实现方法是: 当客户请求数据库连接时,首先查看连接当客户请求数据库连接时,首先查看连接池中是否有空闲连接(指当前没有分配出池中是否有空闲连接(指当前没有分配出去的连接)。如果存在空闲连接,则把连去的连接)。如果存在空闲连接,则把连接分配给客户并作相应处理(即标记该连接分配给客户并作相应处理(即标记该连接为正在使用,引用计数加接为正在使用,引用计数加1)。如果没有)。如果没有空闲连接,则查看当前所开的连接数是不空闲连接,则查看当前所开的连接数

49、是不是已经达到是已经达到maxConn(最大连接数),如(最大连接数),如果没达到就重新创建一个连接给请求的客果没达到就重新创建一个连接给请求的客户;如果达到就按设定的户;如果达到就按设定的maxWaitTime(最大等待时间)进行等待,如果等待(最大等待时间)进行等待,如果等待maxWaitTime后仍没有空闲连接,就抛出后仍没有空闲连接,就抛出无空闲连接的异常给用户。无空闲连接的异常给用户。 当客户释放数据库连接时,先判断该连接的引当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就删除该用次数是否超过了规定值,如果超过就删除该连接,并判断当前连接池内总的连接数是否小

50、连接,并判断当前连接池内总的连接数是否小于于minConn(最小连接数),若小于就将连接(最小连接数),若小于就将连接池充满;如果没超过就将该连接标记为开放状池充满;如果没超过就将该连接标记为开放状态,可供再次复用。可以看出正是这套策略保态,可供再次复用。可以看出正是这套策略保证了数据库连接的有效复用,避免频繁地建立、证了数据库连接的有效复用,避免频繁地建立、释放连接所带来的系统资源开销。释放连接所带来的系统资源开销。 连接池的配置连接池的配置 数据库连接池中到底要放置多少个连接,才能使系统的性数据库连接池中到底要放置多少个连接,才能使系统的性能更佳,用能更佳,用minConn和和maxCon

51、n来限制。来限制。minConn是当应是当应用启动的时候连接池所创建的连接数,如果过大启动将变慢,用启动的时候连接池所创建的连接数,如果过大启动将变慢,但是启动后响应更快;如果过小启动加快,但是最初使用的但是启动后响应更快;如果过小启动加快,但是最初使用的用户将因为连接池中没有足够的连接不可避免的延缓了执行用户将因为连接池中没有足够的连接不可避免的延缓了执行速度。因此应该在开发的过程中设定较小速度。因此应该在开发的过程中设定较小minConn,而在实,而在实际应用的中设定较大际应用的中设定较大minConn。maxConn是连接池中的最是连接池中的最大连接数,可以通过反复试验来确定此饱和点。为

52、此在连接大连接数,可以通过反复试验来确定此饱和点。为此在连接池类池类ConnectionPool中加入两个方法中加入两个方法getActiveSize()和()和getOpenSize(),(),ActiveSize 表示某一时间有多少连接正表示某一时间有多少连接正被使用,被使用,OpenSize表示连接池中有多少连接被打开,反映了表示连接池中有多少连接被打开,反映了连接池使用的峰值。将这两个值在日志信息中反应出来,连接池使用的峰值。将这两个值在日志信息中反应出来, minConn的值应该小于平均的值应该小于平均ActiveSize,而,而maxConn的值的值应该在应该在activeSize

53、和和OpenSize之间。之间。 连接池的关键技术连接池的关键技术 事务处理事务处理 前面讨论的是关于使用数据库连接进行普通的数据库访问。前面讨论的是关于使用数据库连接进行普通的数据库访问。对于事务处理,情况就变得比较复杂。因为事务本身要求原则性的保对于事务处理,情况就变得比较复杂。因为事务本身要求原则性的保证,此时就要求对于数据库的操作符合证,此时就要求对于数据库的操作符合All-All-Nothing原则,即要原则,即要么全部完成,要么什么都不做。如果简单的采用上述的连接复用的策么全部完成,要么什么都不做。如果简单的采用上述的连接复用的策略,就会发生问题,因为没有办法控制属于同一个事务的多

54、个数据库略,就会发生问题,因为没有办法控制属于同一个事务的多个数据库操作方法的动作,可能这些数据库操作是在多个连接上进行的,并且操作方法的动作,可能这些数据库操作是在多个连接上进行的,并且这些连接可能被其他非事务方法复用。这些连接可能被其他非事务方法复用。Connection本身具有提供了本身具有提供了对于事务的支持,可以通过设置对于事务的支持,可以通过设置Connection的的AutoCommit属性为属性为false,显式的调用,显式的调用 commit或或rollback方法来实现。但是要安全、高方法来实现。但是要安全、高效的进行连接复用,就必须提供相应的事务支持机制。方法是:采用效的

55、进行连接复用,就必须提供相应的事务支持机制。方法是:采用显式的事务支撑方法,每一个事务独占一个连接。这种方法可以大大显式的事务支撑方法,每一个事务独占一个连接。这种方法可以大大降低对于事务处理的复杂性,并且又不会妨碍连接的复用。降低对于事务处理的复杂性,并且又不会妨碍连接的复用。 连接管理服务提供了显式的事务开始、结束连接管理服务提供了显式的事务开始、结束(commit或或rollback)声明,以及一个事务注册表,)声明,以及一个事务注册表,用于登记事务发起者和事务使用的连接的对应关系,用于登记事务发起者和事务使用的连接的对应关系,通过该表,使用事务的部分和连接管理部分就隔离开,通过该表,使

56、用事务的部分和连接管理部分就隔离开,因为该表是在运行时根据实际的调用情况动态生成的。因为该表是在运行时根据实际的调用情况动态生成的。事务使用的连接在该事务运行中不能被复用。在实现事务使用的连接在该事务运行中不能被复用。在实现中,用户标识是通过使用者所在的线程来标识的。后中,用户标识是通过使用者所在的线程来标识的。后面的所有对于数据库的访问都是通过查找该注册表,面的所有对于数据库的访问都是通过查找该注册表,使用已经分配的连接来完成的。当事务结束时,从注使用已经分配的连接来完成的。当事务结束时,从注册表中删除相应表项。册表中删除相应表项。 并发并发 为了使连接管理服务有更大的通用性,我们必为了使连

57、接管理服务有更大的通用性,我们必须要考虑到多线程环境,即并发问题。在一个多线须要考虑到多线程环境,即并发问题。在一个多线程的环境下,必须要保证连接管理自身数据的一致程的环境下,必须要保证连接管理自身数据的一致性和连接内部数据的一致性,在这方面性和连接内部数据的一致性,在这方面Java提供很提供很好的支持(好的支持(synchronized关键字),这样就很容关键字),这样就很容易使连接管理成为线程安全的。易使连接管理成为线程安全的。 多数据库服务器多数据库服务器 在实际应用中,应用程序常常需要访问多个在实际应用中,应用程序常常需要访问多个不同的数据库。如何通过同一个连接池访问不同的数不同的数据

58、库。如何通过同一个连接池访问不同的数据库,是应用程序需要解决的一个核心问题据库,是应用程序需要解决的一个核心问题 连接池应用的实现连接池应用的实现一个完整的连接池应用包括三个部分:一个完整的连接池应用包括三个部分:DBConnectionPool类,负责从连接池获取类,负责从连接池获取(或创建或创建)连接、将连接返回给连接池、系统关闭时关闭所有连连接、将连接返回给连接池、系统关闭时关闭所有连接释放所有资源;接释放所有资源;DBConnectionManager类,负责类,负责装载和注册装载和注册JDBC驱动、根据属性文件中定义的属性驱动、根据属性文件中定义的属性创建创建DBConnection

59、Pool、跟踪应用程序对连接池的、跟踪应用程序对连接池的引用等;应用程序对连接池的使用。引用等;应用程序对连接池的使用。 本文实现的数据库连接池包括一个管理类本文实现的数据库连接池包括一个管理类DBConnectionManager,负责提供与多个连接池,负责提供与多个连接池对象对象(DBConnectionPool类类)之间的接口。每一个连之间的接口。每一个连接池对象管理一组封装过的接池对象管理一组封装过的JDBC连接对象连接对象Conn,封装过的封装过的JDBC连接对象连接对象Conn可以被任意数量的可以被任意数量的Model层的组件共享。层的组件共享。 类类Conn 的设计很简单,如下所

60、示:的设计很简单,如下所示: Class Conn Private java. sgl .Connection con; /数据库连数据库连接对象接对象 Public Boolean inUse ; /是否被使用是否被使用 Public long lastAccess; /最近一次释放该连最近一次释放该连接的时间接的时间 Public int useCount; / 被使用次数被使用次数 下面是实现连接池的主要代码:下面是实现连接池的主要代码: / 初始化数据库连接池初始化数据库连接池 public static synchronized void FastInitPool() throws

温馨提示

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

评论

0/150

提交评论