第 JDBC 基础 - images.china-pub.comimages.china-pub.com/ebook195001-200000/196717/ch04.pdf ·...

25
4 JDBC 基础 任何 Web 应用程序的开发都离不开数据库的操作,所以必须实现 Web 应用程序与数 据库的连接。本节就详细介绍了在 Java Web 项目中,如何用 JDBC 访问 MySQL 数据库。 在讲解数据库操作之前首先要配置编程环境,即安装好 MySQLMyElipse 和下载 JDBC 的驱动程序,具体如何下载会在 4.1.2 节介绍。 4.1 认识 JDBC JDBC Java Database Connectivity)全称是 Java 数据库连接,用来执行 SQL Java API开发人员可以使用这些标准 API,来连接和操作数据库,实现数据库应用程序的开发。 4.1.1 为什么要使用 JDBC 当开发人员使用 JDBC 连接数据库时,只要使用 JDBC API 来实现开发程序,就可以 向任何数据库发送 SQL 语句执行工作,而详细的连接程序等配置没有必要手动编写。 JDBC 的工作原理如图 4.1 所示。 Java 应用程序不会直接操作底层的数据库,而是通过 JDBC API JDBC 驱动程序管 理器,委托给底层的各种类型的 JDBC 驱动程序来操作数据库。JDBC 驱动程序可以分为 4 类。 JDBC-OCBC 桥:Java 应用程序数据操作指令在 JDBC 驱动程序管理器的管理下, 经过 JDBC-OCBC 桥驱动转换 ODBC 驱动程序的指令格式,接下来再通过 ODBC 的方式连接数据库。 Java 到本地 APIJava 应用程序数据操作指令在 JDBC 驱动程序管理器的管理下, 转换为调用本地 API。这里所说的本地 API 是指计算机中安装数据库客户端的 API Java 到网络协议:通过网络协议(与具体数据库无关)把 Java 应用程序数据操作 指令发送给数据库服务器。 Java 到数据库协议:通过特定数据库网络协议,把 Java 应用程序数据操作指令发 送给特定类型数据库服务器。

Transcript of 第 JDBC 基础 - images.china-pub.comimages.china-pub.com/ebook195001-200000/196717/ch04.pdf ·...

  • 第4 章 JDBC 基础

    任何 Web 应用程序的开发都离不开数据库的操作,所以必须实现 Web 应用程序与数

    据库的连接。本节就详细介绍了在 Java Web项目中,如何用 JDBC访问MySQL数据库。

    在讲解数据库操作之前首先要配置编程环境,即安装好 MySQL、MyElipse 和下载 JDBC

    的驱动程序,具体如何下载会在 4.1.2节介绍。

    4.1 认识 JDBC

    JDBC(Java Database Connectivity)全称是 Java数据库连接,用来执行 SQL的 Java API。

    开发人员可以使用这些标准API,来连接和操作数据库,实现数据库应用程序的开发。

    4.1.1 为什么要使用 JDBC

    当开发人员使用 JDBC连接数据库时,只要使用 JDBC API来实现开发程序,就可以

    向任何数据库发送 SQL语句执行工作,而详细的连接程序等配置没有必要手动编写。JDBC

    的工作原理如图 4.1所示。

    Java应用程序不会直接操作底层的数据库,而是通过 JDBC API的 JDBC驱动程序管

    理器,委托给底层的各种类型的 JDBC 驱动程序来操作数据库。JDBC 驱动程序可以分为

    4类。

    JDBC-OCBC桥:Java应用程序数据操作指令在 JDBC驱动程序管理器的管理下,

    经过 JDBC-OCBC桥驱动转换 ODBC驱动程序的指令格式,接下来再通过 ODBC

    的方式连接数据库。

    Java到本地 API:Java应用程序数据操作指令在 JDBC驱动程序管理器的管理下,

    转换为调用本地API。这里所说的本地API是指计算机中安装数据库客户端的API。

    Java 到网络协议:通过网络协议(与具体数据库无关)把 Java 应用程序数据操作

    指令发送给数据库服务器。

    Java 到数据库协议:通过特定数据库网络协议,把 Java 应用程序数据操作指令发

    送给特定类型数据库服务器。

  • 第 4 章 JDBC 基础

    113

    J a v a应 用 程 序

    J

    D

    B

    C

    J D B C驱 动 程 序 fo r O ra c le

    J D B C驱 动 程 序 fo r D B 2

    J D B C驱 动 程 序 fo r O ra c le

    J D B C驱 动 程 序 fo r O ra c le

    O ra c le数 据 库

    D B 2数 据 库

    O D B C方 式 连 接 数 据 库

    其 他 数 据 库

    图 4.1 JDBC的工作原理

    在 JDBC 驱动程序中的第一种方式中出现了 ODBC 驱动程序,什么是 ODBC 驱动程

    序呢?ODBC(Openning Database Connection)全称是开放式数据库互连,该驱动程序是

    由微软设计和开发的一种通用、标准的操作数据库的 API,可以说是一种数据库系统应用

    程序的接口规范。该种驱动程序的工作原理如图 4.2所示。

    应 用 程 序

    O

    D

    B

    C

    驱 动 程 序 fo r O ra c le

    驱 动 程 序 fo r S Q L S e rv e r

    驱 动 程 序 fo r A c c e s s

    其 他 驱 动 程 序

    O ra c le数 据 库

    S Q L S e rv e r

    A c c e s s

    其 他 数 据 库

    图 4.2 ODBC的工作原理

    ODBC驱动程序的作用,是把应用程序中操作数据库的指令,转换成某一种数据库相

    关的数据库指令,然后由具体相关的驱动程序传送给数据库。在开发的时候,只需要面对

    统一格式的 ODBC数据源就可以,而不必针对各种不同的数据库做各种不同的设计。

    综上所述,JDBC的功能如下:

    提供多样化的数据库连接方法。

    为各种不同的数据库提供统一的操作界面。

  • Java Web 开发从初学到精通

    114

    4.1.2 JDBC 的下载

    MySQL驱动程序称为 Connector/J,目前最新的版本为 Connector/J 5.1,可以通过下面

    的步骤来实现该驱动程序的下载。

    首先打开下载 MySQL 驱动程序的网站(http://dev.mysql.com/downloads/),如

    图 4.3所示。

    图 4.3 MySQL驱动程序

    打开下载页后,选择 Connector/J 5.1版本后单击该超级链接,这时就会进入下载

    页面,如图 4.4所示。单击“pick a mirror”超级链接就可以下载该驱动程序。

    图 4.4 选择驱动程序安装包类型

    经过上述的两个步骤,就可以完成 MySQL数据库 JDBC的下载。通过这个步骤读者

    应该知道,不同的数据库,甚至是数据库的不同版本,都可能针对不同的下载程序。

    4.1.3 JDBC 的配置

    下载完 MySQL 驱动程序,就可以在应用程序中配置该数据库驱动程序。如何在

    MyEclipse工具中添加、修改和删除该驱动程序的 JRE包呢?具体步骤如下所示。

    在 MyEclipse 的运行界面上选择 Window|Preferences 命令,出现如图 4.5 所示的

    “Preferences”窗口。

  • 第 4 章 JDBC 基础

    115

    图 4.5 “Preferences”窗口

    在“Preferences”窗口的左侧选择 Java|Build Path 选项,出现如图 4.6 所示的

    列表。

    图 4.6 User Libraries列表

    在 User Libraries列表中,单击“New”按钮,在出现的如图 4.7所示的对话框中

    输入名字,单击“OK”按钮就会新建一个“User Libraries”选项。

    不要选上复选框,否则该 Libraries 会成为系统默认的 Libraries。

    注 意

  • Java Web 开发从初学到精通

    116

    接着在 User Build列表中选择“MySQL”选项,单击“Add JARs”按钮把MySQL

    驱动程序(4.1.2 节下载的 MySQL 驱动程序 Connector/J)添加进来,最后效果如图 4.8

    所示。

    图 4.7 新建 User Libraries 图 4.8 添加 JAR包

    如果在项目中想使用该 JAR 包,可以右键单击该项目弹出快捷菜单,然后选择如

    图 4.9所示的选项,这时就会出现如图 4.10所示的窗口。

    图 4.9 Add Libraries选项 图 4.10 “Add Library”窗口

    在“Add Library”窗口中,选择“User Library”选项,单击“Next”按钮就会进入为

    User Librarie 选择具体内容的窗口(如图 4.11 所示),选择刚添加的 MySQL,单击

    “Finish”按钮,就把MySQL驱动程序添加到了项目中。

  • 第 4 章 JDBC 基础

    117

    图 4.11 选择“MySQL”

    当 MySQL 驱动程序添加到具体项目中后,在该项目中就可以使用驱动程序提供的

    API,就可以连接和操作数据库。

    4.2 JDBC 的基础应用

    下载并配置好 JDBC驱动程序后,就要懂得如何使用 JDBC驱动程序的 API,来连接

    和操作数据库。为了方便讲解,本节使用的数据库为MySQL 5.1.29,跟该版本数据库配套

    的 JDBC驱动程序版本为 Connector/J 5.1,开发环境为MyEclipse。

    4.2.1 连接数据库

    使用 JDBC连接数据库存取数据时,必须要执行三个步骤。

    加载及注册适当的 JDBC驱动程序。

    建立到指定数据库的连接对象。

    提交数据库查询和取得查询对象。

    JDBC与数据库建立连接的第一个步骤为加载适当的驱动程序,一般使用如下代码。

    Class.forName()

    当加载完驱动程序后,驱动程序都会建立一个 Driver 对象,并且会让

    DriverManager.registerDriver()自动注册此对象。

    在 JDBC中使用数据库 URL来标识目标数据库,其基本语法格式如下:

    jdbc::

    jdbc为协议名,确定不变。

    指定目标数据库的种类和具体连接方式。

    指定具体的数据库/数据源连接信息,例如数据库服务器的 IP 地址/通信

    端口号、ODBC数据源名称、连接用户名/密码等。

  • Java Web 开发从初学到精通

    118

    一般子名称的格式和内容会随着子协议名的不同而不同。

    假如使用MySQL的驱动程序来连接MySQL,则语法格式如下:

    jdbc:mysql://hostname:port/databasename?param=valuel

    子协议名为:mysql。

    子名称://hostname:port/databasename?param=valuel。

    在子名称中,hostname:表示主机名称,也可以是一个有效 IP地址;Port:表示连接

    数据库使用的端口;databasename:表示连接数据库的名字;param:表示参数的设置,可

    以有多个。

    jdbc:mysql://localhost:3306/sample?user=root&password=root

    上述代码表示连接到一个本地且端口号为 3360的MySQL服务器,并且指定连接的数

    据名为 sample,“?”后的参数代表登录此数据库的名称和密码。

    假如使用 JDBC-ODBC bridge driver驱动程序来连接名为 sample的本地数据库,则语

    法格式如下:

    jdbc:odbc:sample?user=root&password=root

    子协议名为:odbc。

    子名称:sample?user=root&password=root。

    假如使用 Oracle驱动程序来连接名为 sample的本地数据库,则语法格式如下:

    jdbc:oracle:thin://127.0.0.1:1521: sample

    子协议名为:oracle:thin。

    子名称://127.0.0.1:1521: sample。

    假如使用 SQL Server驱动程序来连接名为 sample的本地数据库,则语法格式如下:

    jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=sample

    子协议名为:microsoft:sqlserver。

    子名称://127.0.0.1:1433;databasename=sample。

    当加载完驱动程序并且用数据库 URL 标示一个数据源后,现在就可以建立一个连接

    对象,如下所示:

    String url=" jdbc:mysql://localhost:3306/sample?user=root&password=root";

    Connection con = DriverManager.getConnection(url);

    上述代码也可以改写成如下形式:

    String url=" jdbc:mysql://localhost:3306/sample";

    String user="root";

    String password="root";

    Connection con = DriverManager.getConnection(url,user,password);

    从以上代码可以看出,连接对象主要是通过 DriverManager.getConnection()来实现的。

    注 意

  • 第 4 章 JDBC 基础

    119

    当顺利取得连接对象后,就可以由它来创建一个陈述对象,陈述对象主要用来传送 SQL

    语句到数据库服务器和执行 SQL语句。例如下面产生一个名叫 stmt的陈述对象。

    Statement stmt= con.createStatement();

    在 Statement类中,一般只会用到三种执行语句方法,如下所示。

    executeQuery():执行 SQL查询使用的方法。

    executeUpdate():执行 SQL更新时使用的方法。

    execute():当不知道正要执行的 SQL是查询还是更新时使用的方法。

    当使用 executeQuery()方法时,会回传一个 ResultSet对象,该对象为集合对象。当向

    数据库查询数据的时候,数据库会回传一个结果集合到 JDBC中,这个结果集合就是所谓

    的 ResultSet对象。

    本节介绍的类分别来自如下的 JDBC API中,它们的运行原理如图 4.12所示。

    Java.sql.DriverManager:用来作为初始化的一部分,提供管理 JDBC驱动器设置的

    基本服务。

    Java.sql.Connection:用来表示与一个特定数据库的会话。

    Java.sql.Statement:用来执行 SQL语句并获取它产生的结果。

    R e s u ltS e t R e s u ltS e tR e s u ltS e t

    S ta te m e n t C a lla b le S ta te m e n tP re p a re d S ta te m e n t

    C o n n e c tio n

    图 4.12 运行原理

    4.2.2 使用代码连接数据库

    本案例参考光盘下的源代码\04\JDBCExample。

    4.2.1节已经介绍了 JDBC连接数据库的三个步骤,本节将通过一个具体的实例演示这

    三个步骤。本例的前提:通过MySQL数据库建立一个名叫 testmysql的数据库,然后在该

    数据库中新建一个名叫 student 的表。最后,在表中插入一些数据(读者如果不知道怎么

    操作,可参考第 2章中关于MySQL的介绍)。下面项目将通过 JDBC连接MySQL数据库

    管理系统中的 testmysql数据库,具体步骤如下所示。

    新建一个 Java项目 TestJDBC,其具体设置如图 4.13所示。

    接着新建一个 Class文件 JDBCExample,其具体设置如图 4.14所示。

  • Java Web 开发从初学到精通

    120

    图 4.13 新建 TestJDBC项目 图 4.14 新建 JDBCExample文件

    通过 4.1.3节介绍的 JDBC配置方法,在本项目中加载 JDBC。创建完成后该项目

    的具体目录结构如图 4.15所示。

    图 4.15 目录结构

    在新建的 JDBCExample文件中,添加代码 4.1所示的内容。这里演示了如何通过

    MySQL的 JDBC驱动程序,连接到 MySQL数据库管理系统中的 testmysql数据库,并输

    出数据库中 student表的内容。

    代码 4.1 连接 MySQL 数据:JDBCExample.java

    //引入包

    import java.sql.DriverManager;

    import java.sql.Connection;

    import java.sql.Statement;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    public class JDBCExample {

    public static void main(String[] args) {

    try{

    //加载 mysql数据库驱动程序

    Class.forName("com.mysql.jdbc.Driver");

    String url = "jdbc:mysql://localhost:3306/testmysql?user=root

    &password=root";

    Connection conn = DriverManager.getConnection(url);

    //建立连接对象

  • 第 4 章 JDBC 基础

    121

    Statement stmt = conn.createStatement(); //建立陈述对象

    ResultSet rs = stmt.executeQuery("select * from student");

    //返回 ResultSet对象

    //遍历 ResultSet对象中的各个字段

    while(rs.next()){

    System.out.print("学生的学号: " + rs.getInt(1));

    System.out.print("\t学生的名字: " + rs.getString(2));

    System.out.println("\t 学生的性别: " + rs.getBoolean(3));

    }

    rs.close(); //关闭 ResultSet对象

    stmt.close(); //关闭陈述对象

    conn.close(); //关闭连接对象

    }catch(ClassNotFoundException e){

    System.out.println("找不到指定的驱动程序类!");

    }catch(SQLException e){

    e.printStackTrace();

    }

    }

    }

    运行结果如下:

    学生的学号:1 学生的名字:张 学生的性别:0

    4.2.3 用户界面连接数据库

    为了方便开发人员使用,MyEclipse提供了 Database Explorer(数据库浏览器)来支持

    用户界面连接和操作数据库。Database Explorer 拥有如下功能:支持创建多个数据库连接

    到同一个或者多个数据库;支持 25 种预定义的 JDBC 驱动模板;支持数据库视图等。本

    节将介绍如何使用 Database Explorer,具体步骤如下:

    启动MyEclipse自带的服务器MyEclipse Derby,即通过 启动数据库服务器,

    如图 4.16所示。

    图 4.16 MyEclipse Derby启动信息

    单击按钮 ,在出现的选项中选择 MyEclipse Database Explorer 选项,切换成

    Database Explorer透视图,如图 4.17所示。

    默认 Database Explorer透视图中只有一个建好的数据库连接:MyEclipse Derby,

    该数据库的连接信息如图 4.18所示。

    Driver name:数据库连接的名称。

    Connection URL:数据库连接字符串。

    User Name:连接登录用户名。

  • Java Web 开发从初学到精通

    122

    Password:连接登录密码。

    Driver JARs:用户自己提供的 JAR文件列表。

    Driver classname:JDBC驱动类的完整类名。

    Open on Eclipse Startup:选中这个选项,每次启动时都会自动连接到这个数据库。

    图 4.17 Database Explorer透视图 图 4.18 MyEclipse Derby连接信息

    通过单击 Database Explorer 透视图中的按钮 或者右键单击该选项,在弹出的

    快捷菜单中选择 Open connection命令就可以打开数据库连接,如图 4.19所示。打开数据

    库连接后就可以操作数据库、浏览数据库结构、执行 SQL、编辑数据、查看表结构等。

    打开数据库后可以浏览数据库列表结构,如图 4.20所示。这里可以看到连接中的

    数据库列表。展开 CLASSTCCARS数据库,接着再展开 TABLE表,就可以查看该数据库

    的表列表。选择任何一个表并展开该表,就可以看到该表的结构,如图 4.21所示。该表的

    信息如图 4.22所示。

    图 4.19 打开连接 图 4.20 数据库列表 图 4.21 表结构

  • 第 4 章 JDBC 基础

    123

    图 4.22 数据表 PRODUCTLINE信息

    在图 4.22中有 7个标签,分别显示表格信息,作用如下所示。

    Columns:显示表的列信息。

    Indexes:显示索引的信息。

    Primary Key:显示主键。

    Foreign Key:显示外键。

    Exported Keys:显示导出的主键。

    Preview:显示表格里的数据。

    Row Count:显示表格里数据的行数。

    打开数据库后就可以启动编辑器来编辑SQL,右键单击数据库节点出现快捷菜单,

    然后选择 New SQL Editor命令,就可以打开 SQL编辑器,如图 4.23所示。

    图 4.23 SQL编辑器

    在 SQL编辑器中,编写如下代码。

    select * from classiccars.CUSTOMER

    结果如图 4.23所示。然后单击执行按钮,其运行结果如图 4.24所示。

    图 4.24 SQL编辑器

    通过单击 Database Explorer 透视图中的按钮 ,或者右键单击连接名称,在弹

    出的快捷菜单中选择 Open connection命令,就可以打开数据库连接,如图 4.25所示。

    在图 4.25中有一个名叫 SQL History标签,会保存刚刚执行的 SQL语句,以供以后再

    次使用。在 SQL History透视图中,右键单击刚刚执行的 SQL语句,会弹出三个快捷菜单

    命令,如图 4.26所示。它们的作用如下所示。

  • Java Web 开发从初学到精通

    124

    Open in editor:在 SQL编辑器中重新打开执行语句。

    Remove form history:从历史记录中删除记录。

    Copy to Clipboard:把 SQL语句复制到剪切板。

    图 4.25 执行结果

    图 4.26 SQL History标签

    在 Database Browser 透视图中,右键单击 CLASSICCARS 数据库 TABLE 中

    CUSTOMER 表格,在弹出的快捷菜单中选择 Edit Data 命令,就会出现如图 4.27 所示的

    Edit table "CLASSICCARS"."CUSTOMER"标签。

    图 4.27 编辑表

    在 Database Browser 透视图中,右键单击 CLASSICCARS 数据库 TABLE 中

    CUSTOMER表格,在弹出的快捷菜单中选择 Delete ALL Rows命令,就会删除表里面所

    有的数据,但是表本身并不会被删除。

    4.3 JDBC 的高级应用

    对于 4.2节的 JDBC 应用,由于对于数据库的访问不是很频繁,所以可以简单地在需

    要访问数据库时,就新创建一个连接,用完后就关闭它,这样做不会带来明显的性能上的

    开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁地建立、关闭连接,会

    极大地减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。

  • 第 4 章 JDBC 基础

    125

    4.3.1 数据库连接池简介

    为了避免频繁地建立和关闭数据库,开发人员可以通过建立一个数据库连接池,以

    及一套管理策略来达到连接资源的共享,使得对于数据库的连接可以是高效、安全的

    复用。

    对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁

    分配、释放所造成的问题。把该模式应用到数据库连接管理领域,就是建立一个数据

    库连接池,提供一套高效的连接分配、使用策略,最终目标是实现连接高效、安全的

    复用。

    数据库连接池的基本原理是在内部对象池中,维护一定数量的数据库连接,并对外暴

    露数据库连接获取和返回方法。如图 4.28所示,当程序中需要建立数据库连接时,只需从

    内存中取一个数据库连接来用,而不是新建一个数据库连接。在使用完毕后,只需放回内

    存即可。对于连接的建立和断开,都由连接池自己管理。

    图 4.28 数据库连接池原理

    综上所述,使用数据库连接池具有如下特点。

    资源重用:为了避免频繁地创建、释放数据库连接,必须实现数据库连接的重

    用。

    高效的系统响应:数据库连接池在初始化过程中,一般就会创建若干个数据库连

    接存储在池中备用,所以具有高效的响应。

    统一的连接管理:对于连接数目的创建、断开、管理和关闭等操作,都是由数据

    库连接池统一管理的。

    4.3.2 数据库连接池的原理

    本案例参考光盘下的源代码\04\pooling。

    通过 4.3.1 节可以知道数据库连接池的简单概念,本节将通过一个简单的实例来演示

    如何实现数据库连接池。该连接池是通过 JDBC来实现连接的,具体步骤如下所示。

    首先新建一个 Java项目:pooling,其具体设置如图 4.29所示。

    接着新建两个 class文件:ConnectionPool.java和 ConnectionPoolTest.java,其具体

    设置如图 4.30和图 4.31所示。

  • Java Web 开发从初学到精通

    126

    接着新建一个属性文件:dbpool.properties,具体设置如图 4.32所示。这时整个目

    录结构图 4.33所示。

    图 4.29 新建 pooling项目 图 4.30 新建 ConnectionPool.java文件

    图 4.31 新建 ConnectionPoolTest.java文件 图 4.32 新建 dbpool.properties

    图 4.33 目录结构

  • 第 4 章 JDBC 基础

    127

    打开 pooling/dbpool.properties 编写配置文件,代码 4.2 用来配置数据库连接池连

    接数据库的信息。

  • Java Web 开发从初学到精通

    128

    代码 4.2 连接数据库信息:dbpool.properties

    driverClassName=com.mysql.jdbc.Driver //加载 mysql数据库驱动程序

    username=root //用户名

    password=root //用户密码

    url=jdbc:mysql://localhost:3306/testmysql //数据库 URL

    poolSize=10 //数据库连接数目

    打开 pooling/src/ConnectionPool.java编写数据库连接池程序,代码 4.3用来实现数

    据库连接池。

    代码 4.3 数据库连接池:ConnectionPool.java

    import java.io.FileInputStream;

    import java.sql.Connection;

    import java.sql.SQLException;

    import java.util.Properties;

    import java.util.Vector;

    public class ConnectionPool {

    private Vector pool;

    private String url;

    private String username;

    private String password;

    private String driverClassName;

    private int poolSize = 1; //连接池的大小,也就是连接池中有多少个数据库连接

    private static ConnectionPool instance = null;

    //私有的构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过

    getIstance方法

    private ConnectionPool() {

    init();

    }

    //连接池初始化方法,读取属性文件的内容,建立连接池中的初始连接

    private void init() {

    pool = new Vector(poolSize);

    readConfig();

    addConnection();

    }

    //返回连接到连接池中

    public synchronized void release(Connection conn) {

    pool.add(conn);

    }

    //关闭连接池中的所有数据库连接

    public synchronized void closePool() {

    for (int i = 0; i < pool.size(); i++) {

    try {

    ((Connection) pool.get(i)).close();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    pool.remove(i);

  • 第 4 章 JDBC 基础

    129

    }

    }

    //返回当前连接池的一个对象

    public static ConnectionPool getInstance() {

    if (instance == null) {

    instance = new ConnectionPool();

    }

    return instance;

    }

    //返回连接池中的一个数据库连接

    public synchronized Connection getConnection() {

    if (pool.size() > 0) {

    Connection conn = pool.get(0);

    pool.remove(conn);

    return conn;

    } else {

    return null;

    }

    }

    //在连接池中创建初始设置的数据库连接

    private void addConnection() {

    Connection conn = null;

    for (int i = 0; i < poolSize; i++) {

    try {

    Class.forName(driverClassName);

    conn = java.sql.DriverManager.getConnection(url, username,

    password);

    pool.add(conn);

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }

    ///读取设置连接池的属性文件

    private void readConfig() {

    try {

    String path = System.getProperty("user.dir") + "\\dbpool.

    properties";

    FileInputStream is = new FileInputStream(path);

    Properties props = new Properties();

    props.load(is);

    this.driverClassName = props.getProperty("driverClassName");

    this.username = props.getProperty("username");

    this.password = props.getProperty("password");

    this.url = props.getProperty("url");

    this.poolSize = Integer.parseInt(props.getProperty("poolSize"));

    } catch (Exception e) {

    e.printStackTrace();

  • Java Web 开发从初学到精通

    130

    System.err.println("读取属性文件出错. ");

    }

    }

    }

    打开 pooling/src/ConnectionPoolTest编写测试数据库连接池程序,代码 4.4显示了

    使用数据库连接池与不使用连接池的性能上的差别。

    代码 4.4 数据库连接池性能:ConnectionPoolTest.java

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.ResultSet;

    import java.sql.Statement;

    public class ConnectionPoolTest {

    public static void main(String[] args) throws Exception {

    String sql = " select * from student "; //定义 SQL语句

    long start = System.currentTimeMillis(); //定义一个时间变量

    ConnectionPool pool = null; //定义一个数据库连接池变量

    for (int i = 0; i < 100; i++) {

    pool = ConnectionPool.getInstance(); //初始化数据库连接池

    Connection conn = pool.getConnection(); //获取连接对象

    Statement stmt = conn.createStatement(); //创建陈述对象

    ResultSet rs = stmt.executeQuery(sql); //执行 SQL语句

    while (rs.next()) {

    }

    rs.close(); //关闭数据集

    stmt.close(); //关闭陈述对象

    pool.release(conn); //返回连接对象

    }

    pool.closePool(); //关闭数据库连接池

    System.out.println("经过 100 次的循环调用,使用连接池花费的时间:" +

    (System.currentTimeMillis() - start) + "ms\n");

    String hostName = "127.0.0.1"; //安装数据库的计算机

    String driverClass = " com.mysql.jdbc.Driver";

    //加载 mysql数据库驱动程序

    String url = " jdbc:mysql://hostname:3306/testmysql";

    //数据库 URL

    String user = "root"; //用户名

    String password = "root"; //用户密码

    start = System.currentTimeMillis();

    for (int i = 0; i < 100; i++) {

    Class.forName(driverClass); //加载数据库驱动

    Connection conn = DriverManager.getConnection(url, user,

    password);

    Statement stmt = conn.createStatement(); //创建陈述对象

  • 第 4 章 JDBC 基础

    131

    ResultSet rs = stmt.executeQuery(sql); //执行 SQL语句

    while (rs.next()) {

    }

    rs.close();

    stmt.close();

    conn.close();

    }

    System.out.println("经过 100 次的循环调用,不使用连接池花费的时间:" +

    (System.currentTimeMillis() - start) + "ms");

    }

    }

    运行结果如下:

    经过 100次循环调用,使用连接池花费的时间 4000ms

    经过 100次循环调用,不使用连接池花费的时间 18000ms

    虽然测试程序的运行结果,会根据具体的计算机性能而显示的时间不一样,但是不使

    用数据库连接池花费的时间,基本上是使用数据库连接池的 n倍。

    4.3.3 配置和使用服务器 Tomcat 连接池

    在开发具体项目时编写数据库连接池是没有必要的,因为现在已经存在许多的数据库

    连接池的现成的组件,只要配置一下就可以使用。而且现在许多应用服务器都已经内置了

    数据库连接池,如 Tomcat 服务器、Jboss 服务器和 WebLogic 服务器等。下面将具体地讲

    解如何配置服务器 Tomcat数据库连接池,具体步骤如下:

    打开文件夹 Tomcat 6.0根目录\conf的文件 context.xml。代码 4.5中对配置代码的

    修改使得 Tomcat支持数据库连接池。

    代码 4.5 配置代码修改:context.xml

    WEB-INF/web.xml

  • Java Web 开发从初学到精通

    132

    maxActive="100" maxldle="30" maxWait="10000"

    username="root" password="root"

    driverClassName=" com.mysql.jdbc.Driver"

    url=" jdbc:mysql://localhost:3306/testmysql"

    />

    新建一个Web项目:DBWater。在该项目中新建一个 class文件:DBWater.java,

    这时整个目录结构如图 4.34所示。

    图 4.34 目录结构

    打开 DBWater/WebRoot/WEB-INF/web.xml 文件,修改某些代码使得包含有代码

    4.6的项目能够使用数据库连接池连接数据库。

    代码 4.6 配置代码修改:web.xml

    index.jsp

    Connection Pool

    >

    "jdbc/DBWater

    >

    javax.sql.DataSource

    Container

    Shareable

  • 第 4 章 JDBC 基础

    133

    打开 DBWater/src/DBWater.java文件,添加某些代码使得代码 4.7能够通过连接池

    连接数据库。

    代码 4.7 支持连接池:DBWater.java

    //引入包

    package com.cjg.test;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import javax.naming.InitialContext;

    import javax.sql.DataSource;

    import java.sql.Statement;

    public class DBWater {

    //定义三个对象 name 、number、sex

    String name;//姓名

    int number;//编号

    boolean sex;//性别

    public String getName() {

    return name;

    }

    public int getNumber() {

    return number;

    }

    public boolean isSex() {

    return sex;

    }

    //初始化一些对象

    public void init() {

    try {

    InitialContext initc = new InitialContext();

    //创建 InitialContext对象

    if (initc == null)

    throw new Exception("No Context");

    /*

    * 在下面的字符串 "java:comp/env/jdbc/DBWater"中, *"java:comp/

    env/"是不变的,

    * 而"jdbc/DBWater"Tomcat服务器中配置文件数据源名称

    */

    //创建数据源对象 ds

    Context context=(Context) initc.lookup("java:comp/env");

    DataSource ds = (DataSource)context.lookup("jdbc/DBWater");

    if (ds != null) {

    Connection conn = ds.getConnection(); //得到连接对象

    if (conn != null) {

    Statement stmt=conn.createStatement(); //创建陈述对象

    //得到运行结果

    ResultSet rst=stmt.executeQuery("select * from student");

    //遍历运行结果

    while (rst.next()) {

  • Java Web 开发从初学到精通

    134

    number=rst.getInt(1);

    name=rst.getString(2);

    sex=rst.getBoolean(3);

    }

    conn.close(); //关闭连接对象

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    打开 DBWater/WebRoot/index.jsp文件,添加代码 4.8来测试运行结果。

    代码 4.8 测试页面:index.jsp

    连接池测试

    学生的学号:

    学生的名字:

    学生的性别:

    单击工具栏上的按钮 ,把该项目发布到服务器。然后单击工具栏上的按钮

    ,启动服务器。最后打开浏览器,在地址栏目里输入地址 http://localhost:8080/

    DBWater/index.jsp,运行结果如图 4.35所示。

    图 4.35 运行结果

    由于在 DBWater 项目中连接到的表 student 中只有一行字段,所以在代码 注 意

  • 第 4 章 JDBC 基础

    135

    DBWater.java 是否循环遍历产生的结果都一样。

  • Java Web 开发从初学到精通

    136

    4.4 小结

    JDBC是一种可用于执行 SQL语句的 Java应用程序设计接口,JDBC为数据库应用开

    发人员、数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以

    用纯 Java语言编写完整的数据库应用程序。

    本章讲解了如何下载、配置和使用 JDBC 数据库驱动程序。在使用 JDBC 连接数据

    库时,除了可以通过 Java语言具体编写外,还可以通过 MyEclipse的数据库服务器视图

    来实现。

    在性能上为了解决数据库连接的瓶颈问题,出现了数据库连接池的模型。本章还具体

    地讲解了如何配置服务器 Tomcat 的内置数据库连接池,并学习在具体项目中如何使用数

    据库连接池。