1、1 PostgreSQL数据库简介PostgreSQL是一种对象关系型数据库管理系统(ORDBMS),也是目前最复杂、功能最强大、特性最丰富的自由软件数据库系统。它起源于伯克利(BSD)的数据库研究计划,是目前最重要的开源数据库产品之一,有着非常广泛的用户。PostgreSQL支持事务、子查询、多版本并发控制、数据完整性检查等特性,并且支持多语言的应用开发。它能在包括Linux、FreeBSD和Windows等多种平台下运行。1.1 PostgreSQL的 下 载 和 安 装要在Windows操作系统下安装PostgreSQL,计算机系统必须满足下面要求: CPU:Intel或AMD的32位C
2、PU。操作系统:WindowsXP或WindowsServer2003。磁盘格式:文件系统为NTFS格式。用户:必须以系统管理员身份安装PostgreSQL。PostgreSQL从8.0版开始提供Windows下的安装程序,可以到http:/www.postgresql.org/下载最新的PostgreSQL。假设下载的是文件名为postgresql-8.3.8-1.zip的压缩文件,将其解压到临时目录,解压后产生4个文件。双击postgresql-8.3.msi文件即开始安装,首先弹出选择安装过程使用的语言以及说明界面,接着出现如图1.20所示的安装选项界面。默认情况下,区域语言支持和PL/
3、Java以及一些开发工具都不被安装。如果希望安装它们,请选择这些选项。在该界面还可以指定PostgreSQL的安装目录。默认的安装目录为“C:ProgramFilesPostgreSQL8.3”,如果要修改安装目录,可单击【浏览】按钮改变安装路径,如这里指定的安装路径为“C:PostgreSQL8.3”。单击【前进】按钮,进入服务配置界面,如图1.21所示。图1.20安装选项界面图1.21服务配置界面选中“作为系统服务安装”复选框,将PostgreSQL作为Windows的一个服务安装。这样当Windows操作系统启动时自动启动PostgreSQL服务器。在“账户名称”文本框中输入一个账户名,
4、这是一个特殊的Windows用户账户,用来运行PostgreSQL数据库服务器。在下面文本框中输入账户的密码。单击【前进】按钮。如果账户不存在,弹出如图1.22所示的对话框提示账户没有找到并询问是否创建该账户,单击【是】按钮创建账户。图1.22提示账户不存在对话框如果账户已存在,将发生错误。应该先删除该账户,然后再安装PostgreSQL。可以通过“控制面板”中的“计算机管理”工具删除用户,也可以在命令提示符下使用命令删除用户。首先以管理员身份登录系统,启动命令提示符,输入net user username /delete,这里username为要删除的用户名。如果指定的口令不够复杂,将弹出如
5、图1.23所示的对话框,提示是否由安装程序随机生成一个密码并替换它。图1.23提示创建随机口令对话框如果选择【是】按钮,安装程序随机生成一个口令并弹出一个对话框,上面显示随机生成的口令,应该记录下该口令以便将来升级时使用。单击【确定】按钮,进入初始化数据库群界面,如图1.24所示。图1.24初始化数据库群界面在该页面中指定是否初始化数据库群,指定数据库服务器监听的端口号(默认端口号为5432),服务器和客户端的字符编码,服务器管理员的账号和口令等。单击【前进】按钮,在出现的页面中指定数据库使用的过程语言,PL/pgSQL语言是PostgreSQL默认的过程语言,它在语法上与Oracle的PL/
6、SQL类似。单击【前进】按钮,进入“设置辅助模块”页面。选择要安装到默认的模板数据库中的模块等。再单击【前进】按钮,安装程序开始安装PostgreSQL。如果没有错误,最后出现安装完毕界面,单击【完成】按钮结束安装。1.2 使 用 pgAdminIII 操 作 数 据 库在客户能够对数据库操作之前必须连接到数据库。连接数据库可以使用PostgreSQL提供的pgAdminIII工具或psql工具。pgAdminIII是图形界面的工具,psql是命令行界面的工具。本节首先介绍使用pgAdminIII连接数据库,使用psql连接数据库的方法在下节介绍。pgAdminIII是PostgreSQL安装
7、程序自带的一个图形用户界面的管理工具。使用该工具可以方便、直观地管理PostgreSQL数据库。要启动pgAdminIII,选择“开始”“所有程序”PostgreSQL8.3pgAdminIII,首先显示pgAdminIII的主窗口。在主窗口左侧的“对象浏览器”中双击“服务器”下方的节点,出现一个密码验证对话框。输入数据库服务器管理员用户密码,然后单击【确定】按钮。如果密码正确,pgAdminIII将连接到PostgreSQL服务器,然后就可以对PostgreSQL的各种对象进行管理。pgAdminIII的主窗口如图1.25所示。图1.25 pgAdminIII工具的主窗口使用pgAdminI
8、II几乎可以完成所有的数据库管理操作。例如,可以管理服务器、数据库、表空间、登录用户和组用户、管理模式和模式对象(数据表,视图)等。1. 创 建 数 据 库 角 色PostgreSQL的每个数据库都必须拥有所有者,因此,在创建数据库前应该创建角色。在pgAdminIII的对象浏览器中右击“登录角色”,在弹出的快捷菜单中选择“新建登录角色”命令,打开“新建登录角色”对话框,在“角色名称”中输入bookstore,密码输入bookstore,在“角色权限”组框中选中“可以创建数据库对象”复选框。最后,单击【确定】按钮。2. 创 建 数 据 库在pgAdminIII的对象浏览器中右击“数据库”,在弹
9、出的快捷菜单中选择“新建数据库”命令,打开“新建数据库”对话框。在“名称”中输入bookstore,在“所有者”列表框中选中bookstore角色,单击【确定】按钮,则可创建一个名为bookstore的数据库。3. 创 建 数 据 库 对 象数据表是数据库最重要的对象。下面在bookstore数据库中创建一个名为books的数据表。展开bookstore数据库,选择模式中的public模式,右击“数据表”,在弹出的快捷菜单中选择“新建数据表”命令,打开“新建数据表”对话框。在“属性”页的“名称”中输入books,在“所有者”列表框中选择bookstore。在“字段”页中添加表的字段。在“约束”
10、页中添加主键约束。操作完成后在SQL页中可以看到生成的SQL语句,如下所示:CREATETABLEbooks(bookidcharacter(5), -书号titletext, -书名authorcharactervarying(20), -作者publishercharactervarying(40), -出版社pricedoubleprecision, -价格CONSTRAINTpk_bidPRIMARYKEY(bookid) -定义主键)WITH(OIDS=FALSE);ALTERTABLEbooksOWNERTObookstore;最后,单击【确定】按钮创建books数据表。4. 操
11、作 数 据 库 对 象数据表创建好后,可以使用pgAdminIII的查询工具完成数据库操作。要打开查询窗口,选择“工具”菜单中的“查询工具”命令或单击【执行任意的SQL查询】按钮。打开如图1.26所示的查询窗口。图1.26 pgAdminIII的查询工具在该窗口中可以执行任意的SQL语句,如使用INSERT语句向表中插入数据。在窗口中输入SQL语句后,单击工具栏的【执行查询】按钮或按F5键即可执行该SQL语句。假设使用下面的SQL语句向books表中插入若干数据:INSERTINTObooksVALUES(204,HeadFirstServletsINSERTINTObooksVALUES(2
12、01,Servlets与JSP核心教程,MartyHall,清华大学出版社,45);INSERTINTObooksVALUES(202,Tomcat与JavaWeb开发技术详解,孙卫琴,机械工业出版社,45);INSERTINTObooksVALUES(203,JSP完全学习手册,张银鹤,清华大学出版社,69);INSERTINTObooksVALUES(205,JavaEE5开发指南,KevinMukhar,机械工业出版社,49.00);使用该查询工具还可以查询表中的数据,查询结果在下面的“输出窗口”中显示。1.3 使 用 psql工 具 操 作 数 据 库在PostgreSQL8.3程序组
13、中选择“命令提示符”命令,启动一个命令提示符窗口,在提示符下输入:C:PostreSQL8.3binpsql-Upostgreshlocalhost这里,-Upostgres表示作为postgres用户连接服务器,-hlocalhost表示连接运行在本地主机上的数据库服务器。如果没有指定用户名,PostgreSQL将认为使用登录主机的用户名。如果省略了用户名和数据库名,表明以操作系统的身份登录到数据库服务器,此时要求在PostgreSQL服务器中有一个与操作系统同名的登录用户和数据库。使用psql-help可以显示psql的所有命令选项。其中,最重要的选项包括:-U选项允许指定与登录到操作系统
14、用户名不同的用户名登录到数据库。-d选项指定连接的数据库。-h选项指定连接的主机名。-p选项用来指定数据库服务器的端口号。psql的界面如图1.27所示。图1.27 psql工具的运行界面提示符“postgres=#”表示连接到名为“postgres”的数据库,该数据库是默认数据库。“#”表示是作为数据库超级用户连接的。“postgres”是默认的超级用户。psql客户程序具有很多特征,它使我们对PostgreSQL的使用变得很容易。除了可以使用PostgreSQL命令(SELECT,INSERT,UPDATE,CREATETABLE等)外,psql还提供了许多内部命令,这些命令称为元命令(m
15、eta-command)。PostgreSQL命令被发送到服务器,而元命令由psql自身处理。元命令都是由反斜线()开头,后跟一个或多个字母表示的命令,有些命令还可以带参数。表1.2给出了一些常用的元命令。与SQL命令不同,元命令不需要使用分号结束,直接按回车即可。表 1.2 psql常 用 的 元 命 令命 令 功 能?显示所有psql元命令的帮助信息q退出psql工具,返回到操作系统hcmd显示指定的SQL命令的帮助信息d显示当前数据库中表的信息d显示指定表的结构信息efile编辑当前缓冲区内容或者使用外部编辑器编辑指定的文件l显示所有数据库信息ofile将查询结果发送到指定的文件下面介绍
16、如何使用psql创建数据库用户、创建数据库和创建数据库对象。1. 创 建 数 据 库 用 户只有数据库管理员才能创建用户。首先以超级用户身份登录到PostgreSQL,然后使用下面的SQL语句创建一个名为bookstore的数据库用户:postgres=#CREATEUSERbookstorepostgres-#LOGINpostgres-#CREATEDBpostgres-#PASSWORDbookstore;CREATEUSER要结束SQL语句,应该输入分号(;)然后按回车。该语句中,LOGIN表示该用户是登录用户,CREATEDB表示该用户具有创建数据库对象的权限,PASSWORD指定用
17、户的口令,它使用单引号定界。使用“du”元命令可以显示用户的状态。2. 创 建 bookstore数 据 库下面的SQL语句创建一个名为bookstore的数据库,该数据库属于bookstore用户。postgres=#CREATEDATABASEbookstorepostgres-#OWNERbookstore;OWNERbookstore短语指定数据库的所有者(owner),对象的所有者具有在该对象上所有的操作权限。使用“l+”元命令,可以查看数据库是否创建成功。3. 创 建 数 据 库 对 象超级用户postgres可以为其他用户创建数据库对象,但数据库对象一般由数据库所有者创建。如果要
18、以用户bookstore的身份登录到bookstore数据库,请先退出psql,然后使用bookstore用户名连接到bookstore数据库:C:PostreSQL8.3binpsqlUbookstoredbookstore该命令以bookstore用户身份连接到bookstore数据库。接下来需要输入用户口令,最后出现的提示符如下:bookstore=在该提示符下就可以使用SQL语句创建数据库对象,并且这些对象将存于bookstore数据库的public模式中。例如,使用下面SQL语句创建books表:CREATETABLEbooks(bookidcharacter(5)PRIMARYKE
19、Y,titletext,authorcharactervarying(20),publishercharactervarying(40),pricedoubleprecision);使用SQLINSERT语句向表中插入若干数据。在psql的提示符下不但可以直接执行SQL命令,也可以执行SQL脚本文件,使用的命令为“i”,它的格式为:$i例如,要执行“C:tempscript.sql”文件,命令如下:bookstore=#iC:/temp/script.sqlPostgreSQL数据库功能十分强大,要了解其他内容可参阅联机文档或有关参考文献。2.3传统的数据库连接方法JDBCAPI是在java.
20、sql包和javax.sql包中定义的,其中包括JDBCAPI用到的所有类和接口。下面是主要的类和接口,DriverManager类和Driver接口、Connection接口、Statement接口、PreparedStatement接口、CallableStatement接口、ResultSet接口、SQLException类。下面是传统的数据库连接的步骤。2.3.1 加 载 驱 动 程 序要使应用程序能够访问数据库,首先必须加载驱动程序。驱动程序是实现了Driver接口的类,它一般由数据库厂商提供。加载JDBC驱动程序最常用的方法是使用Class类的forName()静态方法,该方法的声
21、明格式为:publicstaticClassforName(StringclassName)throwsClassNotFoundException参数className为一字符串表示的完整的驱动程序类的名称。如果找不到驱动程序将抛出ClassNotFoundException异常。该方法返回一个Class类的对象。对于不同的数据库,驱动程序的类名是不同的。如果使用ODBC-JDBC桥驱动程序连接数据库,则使用JDK自带的驱动程序,名称为“sun.jdbc.odbc.JdbcOdbcDriver”,要加载该驱动程序,可使用下面的语句:Class.forName(“sun.jdbc.odbc.J
22、dbcOdbcDriver“);如果要加载数据库厂商提供的专门的驱动程序,应该给出专门的驱动程序名。例如,要加载PostgreSQL数据库驱动程序应使用下列语句:Class.forName(“org.postgresql.Driver“);这里,org.postgresql.Driver为PostgreSQL的驱动程序类名。2.3.2 建 立 连 接 对 象驱动程序加载成功后应使用DriverManager类的getConnection()建立数据库连接对象。1. DriverManager 类DriverManager类是JDBC的管理层,作用于应用程序和驱动程序之间。DriverManag
23、er类跟踪可用的驱动程序,并在数据库和驱动程序之间建立连接。DriverManager类维护一个注册的Driver类的列表。建立数据库连接的方法是调用DriverManager类的静态方法getConnection(),该方法的声明格式为: publicstaticConnectiongetConnection(Stringdburl) publicstaticConnectiongetConnection(Stringdburl,Stringuser,Stringpassword)这里字符串参数dburl表示JDBCURL,user表示数据库用户名,password表示口令。调用该方法,Dr
24、iverManager类试图从注册的驱动程序中选择一个合适的驱动程序,然后建立到给定的JDBCURL的连接。如果不能建立连接将抛出SQLException异常。2. JDBC URLJDBCURL与一般的URL不同,它用来标识数据源,这样驱动程序就可以用它建立一个连接。下面是JDBCURL的标准语法,它包括三个部分,中间用冒号分隔:jdbc:其中,jdbc表示协议,JDBCURL的协议总是jdbc。subprotocol表示子协议,它表示驱动程序或数据库连接机制的名称,如使用JDBC-ODBC桥驱动程序访问数据库,子协议就是odbc,如果使用专用驱动程序,子协议名通常为数据库厂商名,如orac
25、le。subname为子名称,它表示数据库标识符,该部分内容随数据库驱动程序的不同而不同。如果通过JDBC-ODBC桥驱动程序连接数据库,URL的形式为:jdbc:odbc:DataSource上面三个部分组成一个整体字符串就是JDBCURL,例如:Stringdburl=“jdbc:odbc:bookDS“;它表示通过ODBC子协议连接到名为bookDS的数据源。如果使用数据库厂商提供的专门的驱动程序连接数据库,JDBCURL可能更复杂一些。例如,要连接PostgreSQL数据库,它的JDBCURL为:jdbc:postgresql:/localhost:5432/dbname这里,loca
26、lhost表示主机名或IP地址,5432为数据库服务器的端口号,dbname为数据库名。下面代码说明了如何以bookstore用户连接到PostgreSQL数据库。这里的数据库名为bookstore、用户名为bookstore、口令为bookstore:Stringdburl=“jdbc:postgresql:/localhost:5432/bookstore“;Connectionconn=DriverManager.getConnection(dburl,“bookstore“,“bookstore“);表7.1列出了常用的数据库JDBC连接代码。表 7.1 常 用 数 据 库 的 JDB
27、C 连 接 代 码数 据 库 连 接 代 码Oracle Class.forName(“oracle.jdbc.driver.OracleDriver“);Connectionconn=DriverManager.getConnection(“jdbc:oracle:thin:dbServerIP:1521:ORCL“,user,password);OracleXE Class.forName(“oracle.jdbc.driver.OracleDriver“);Connectionconn=DriverManager.getConnection(“jdbc:oracle:thin:dbSer
28、verIP:1521/XE“,user,password);MySQL Class.forName(“com.mysql.jdbc.Driver“);Connectionconn=DriverManager.getConnection(“jdbc:mysql:/dbServerIP:3306/dbName?user=userNamePostgreSQL Class.forName(“org.postgresql.Driver“);Connectionconn=DriverManager.getConnection(“jdbc:postgresql:/dbServerIP/dbName“,use
29、r,password);DB2 Class.forName(“.DB2Driver“);Connectionconn=DriverManager.getConnection(“jdbc:db2:/dbServerIP:6789/dbName“,user,password);Sybase Class.forName(“com.sybase.jdbc2.SybDriver“);Connectionconn=DriverManager.getConnection(“jdbc:sybase.Tds:dbServerIP:2638“,user,password);ODBC Class.forName(“
30、sun.jdbc.odbc.JdbcOdbcDriver“);Connectionconn=DriverManager.getConnection(“jdbc:odbc:DSNName“,user,password);SQLServer Class.forName(“com.micrsoft.jdbc.sqlserver.SQLServerDriver“);Connectionconn=DriverManager.getConnection(“jdbc:microsoft:sqlserver:/dbServerIP:1433;databaseName=master“,user,password
31、);表中forName()方法中的字符串为驱动程序名,getConnection()方法中的字符串即为JDBCURL,其中dbServerIP为数据库服务器的主机名或IP地址,端口号为相应数据库的默认端口。2.3.3 创 建 语 句 对 象通过Connection对象,可以创建语句(Statement)对象。对于不同的语句对象,可以使用Connection接口的不同方法创建。例如,要创建一个简单的Statement对象可以使用createStatement()方法,创建PreparedStatement对象应该使用prepareStatement()方法,创建CallableStatement
32、对象应该使用prepareCall()方法。下面的代码将创建一个简单的Statement对象:Statementstmt=conn.createStatement();2.3.4 获 得 SQL语 句 的 执 行 结 果执行SQL语句使用Statement对象的方法。对于查询语句,调用executeQuery(Stringsql)方法,该方法的返回类型为ResultSet。ResultSet对象保存查询的结果集,再通过调用ResultSet的方法可以对查询结果的每行进行处理,如:Stringsql=“SELECT*FROMbooks“;ResultSetrst=stmt.executeQuer
33、y(sql);while(rst.next()out.print(rst.getString(1)+“t“);对于DDL语句如CREATE、ALTER、DROP和DML语句如INSERT、UPDATE、DELETE等须使用语句对象的executeUpdate(Stringsql)方法。该方法返回值为整数,用来指示被影响的行数。2.3.5 关 闭 建 立 的 对 象在Connection接口、Statement接口和ResultSet接口中都定义了close()方法。当这些对象使用完毕后应使用close()方法关闭建立的对象,关闭对象应该按与建立对象相反的顺序关闭。2.3.6 简 单 的 应 用
34、 示 例本示例程序从JSP页面输入一个书号,查询该书的信息。本例的设计采用了MVC设计模式,其中bookQuery.jsp、showBook.jsp和error.jsp实现视图,BookBean类实现模型,BookQueryServlet类实现控制器。下面是bookQuery.jsp页面代码。程序7.1 bookQuery.jsp请输入书号:_下面代码是一个JavaBeans,用来存放图书信息。程序7.2 BookBean.javapackagecom.model;publicclassBookBeanprivateStringbookid=“;privateStringtitle=“;pri
35、vateStringauthor=“;privateStringpublisher=“;privatedoubleprice=0.0;publicBookBean()publicBookBean(StringbookId,Stringauthor,Stringtitle,Stringpublisher,doubleprice)this.bookid=bookId;this.title=title;this.author=author;this.publisher=publisher;this.price=price;publicStringgetBookid()returnthis.booki
36、d;publicStringgetTitle()returntitle;publicStringgetAuthor()returnthis.author;publicStringgetPublisher()returnpublisher;publicdoublegetPrice()returnprice;publicvoidsetBookid(Stringbookid)this.bookid=bookid; publicvoidsetTitle(Stringtitle)this.title=title;publicvoidsetAuthor(Stringauthor)this.author=a
37、uthor; publicvoidsetPublisher(Stringpublisher)this.publisher=publisher;publicvoidsetPrice(doubleprice)this.price=price; _下面的Servlet连接数据库并根据表单传递来的书号查询数据库。程序7.3 BookQueryServlet.javapackagecom.control;importjava.io.*;importjava.sql.*;importjavax.servlet.*;importjavax.servlet.http.*;importcom.model.Boo
38、kBean;publicclassBookQueryServletextendsHttpServletConnectiondbConnection;publicvoidinit()Stringdriver=“org.postgresql.Driver“;Stringdburl=“jdbc:postgresql:/127.0.0.1:5432/bookstore“;Stringusername=“postgres“;Stringpassword=“postgres“;tryClass.forName(driver);/加载数据库驱动程序/创建数据库连接对象dbConnection=DriverM
39、anager.getConnection(dburl,username,password);catch(ClassNotFoundExceptione1)catch(SQLExceptione2)publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOExceptionStringbookid=request.getParameter(“bookid“);tryStringsql=“SELECT*FROMbooksWHEREbookid=?“;Prepared
40、Statementpstmt=dbConnection.prepareStatement(sql);pstmt.setString(1,bookid);ResultSetrst=pstmt.executeQuery();if(rst.next()BookBeanbook=newBookBean();book.setBookid(rst.getString(“bookid“);book.setTitle(rst.getString(“title“);book.setAuthor(rst.getString(“author“);book.setPrice(rst.getDouble(“price“
41、);book.setPublisher(rst.getString(“publisher“);request.getSession().setAttribute(“book“,book);RequestDispatcherview=request.getRequestDispatcher(“/showBook.jsp“);view.forward(request,response);elseRequestDispatcherview=request.getRequestDispatcher(“/error.jsp“);view.forward(request,response);catch(S
42、QLExceptione)e.printStackTrace();publicvoiddestroy()trydbConnection.close();catch(Exceptione)e.printStackTrace();_程序在init()方法中建立数据库连接对象,在doPost()方法中创建结果集对象,并从中查询数据。destroy()方法关闭数据库的连接。在web.xml文件中加入下面代码:bookqueryServletcom.control.BookQueryServletbookqueryServlet/bookquery.do下面的JSP页面根据Servlet传递来的JavaBeans显示查询的图书信息。程序7.4showBook.jsp书号:书名:作者:出版社:价格:_当查询的图书不存在时,显示下面的页面。程序7.5 error.jsp该书不存在。返回_启动浏览器,在地址栏中输入下面德URL:http:/localhost:8080/bookstore/bookQuery.jsp。程序运行结果如图7.12和图7.13所示。图7.12 bookQuery.jsp页面图7.13数据库访问结果