﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-大道至简-文章分类-Oracle</title><link>http://www.blogjava.net/hellotony/category/4789.html</link><description>道生一，一生二，二生三，三生万物。万物负阴而抱阳，冲气以为和。</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 04:02:29 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 04:02:29 GMT</pubDate><ttl>60</ttl><item><title>J2EE应用中与Oracle数据库的连接</title><link>http://www.blogjava.net/hellotony/articles/49126.html</link><dc:creator>Tony</dc:creator><author>Tony</author><pubDate>Tue, 30 May 2006 14:49:00 GMT</pubDate><guid>http://www.blogjava.net/hellotony/articles/49126.html</guid><wfw:comment>http://www.blogjava.net/hellotony/comments/49126.html</wfw:comment><comments>http://www.blogjava.net/hellotony/articles/49126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hellotony/comments/commentRss/49126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hellotony/services/trackbacks/49126.html</trackback:ping><description><![CDATA[
		<font size="2">在J2EE应用程序开发中，应用程序与数据库连接的建立是我们经常遇到的问题之一。在这里我主要谈谈在本地应用程序中通过OCI方式、thin方式和
JdbcOdbc桥方式连接Oracle数据库，在iPlanet Application Server 6.5和Sun Java System
Application Server 7中对Oracle数据库连接池的配置以及应用中如何从连接池中获得连接 <br /><br />
一、本地通过JDBC获得Oracle数据库连接 <br /><br />
通过JDBC获得Oracle数据库连接，有三种方式：OCI方式、thin方式和JdbcOdbc桥方式。OCI方式依赖于本地的动态链接库，如果在本
地安装了Oracle数据库客户端可以采用该方式；而thin方式为纯java的数据库连接方式；JdbcOdbc桥方式依赖于本地ODBC数据库源的配
置，这种方式一般不太被采用。 <br /><br />
1、OCI方式 <br /><br />
先在本地安装Oracle客户端，安装完之后，在安装的路径中可以找到…/jdbc/lib/classes12.zip文件，我们在环境变量classpath中设置classes12.zip所在的路径。 <br /><br />
然后通过以下的数据库连接类，在本地通过OCI方式获得Oracle数据库连接 <br /><br />
/** <br />
* 在本地获得数据库连接 <br />
*/ <br /><br />
package com.j2ee.db; <br /><br />
import java.util.*; <br />
import java.sql.*; <br />
import javax.sql.*; <br />
import java.io.*; <br />
import oracle.jdbc.driver.*; <br />
import javax.naming.*; <br /><br />
/** <br />
* 通过OCI方式获得Oracle数据库连接 <br />
*/ <br />
public class DbConnection <br />
{ <br />
final static String sDBDriver = "oracle.jdbc.driver.OracleDriver"; <br />
final static String sConnStr = "jdbc:oracle:oci8:sr/sr@ora199"; <br /><br />
/** <br />
* <br />
*/ <br />
public DbConnection() <br />
{ <br />
} <br /><br />
/** <br />
* 获得Oracle数据库连接 <br />
*/ <br />
public java.sql.Connection connectDbByOci() <br />
{ <br />
java.sql.Connection conn=null; <br />
try <br />
{ <br />
Class.forName(sDBDriver); <br />
conn = DriverManager.getConnection(sConnStr); <br />
} <br />
catch (Exception e) <br />
{ <br />
System.out.println("ERROR:"+e.getMessage()); <br />
} <br />
return conn; <br />
} <br />
} <br />
在连接字符串 "jdbc:oracle:oci8:sr/sr@ora199" 中，"sr/sr"为Oracle用户的用户名和口令，"ora199"为数据库服务名。 <br /><br />
2、thin方式 <br /><br />
先到Oracle技术网（http:
//otn.oracle.com/global/cn/software/tech/java/sqlj_jdbc/index.html）下载
Oracle JDBC Drivers，同样地将下载后的zip文件的路径设置在环境变量classpath。 <br /><br />
然后通过以下的数据库连接类，在本地通过thin方式获得Oracle数据库连接。 <br /><br />
/** <br />
* 在本地获得数据库连接 <br />
*/ <br /><br />
package com.j2ee.db; <br /><br />
import java.util.*; <br />
import java.sql.*; <br />
import javax.sql.*; <br />
import java.io.*; <br />
import oracle.jdbc.driver.*; <br />
import javax.naming.*; <br /><br />
/** <br />
* 通过thin方式获得Oracle数据库连接 <br />
*/ <br />
public class DbConnection <br />
{ <br />
private String sConnStr = ""; <br /><br />
/** <br />
* 缺省构造器 <br />
*/ <br />
public DbConnection() <br />
{ <br />
sConnStr = "jdbc:oracle:thin:@10.1.4.199:1521:ora199"; <br />
} <br /><br />
/** <br />
* @param ip,serviceName <br />
*/ <br />
public DbConnection(String ip,String serviceName) <br />
{ <br />
sConnStr = "jdbc:oracle:thin:@"+ip+":1521:"+serviceName; <br />
} <br /><br />
/** <br />
* 通过thin方式获得Oracle数据库的连接. <br />
*/ <br />
public java.sql.Connection connectDbByThin() <br />
{ <br />
java.sql.Connection conn=null; <br />
try <br />
{ <br />
Class.forName(sDBDriver); <br />
conn = DriverManager.getConnection(sConnStr,"sr","sr"); <br />
} <br />
catch (Exception e) <br />
{ <br />
System.out.println("ERROR:"+e.getMessage()); <br />
} <br />
return conn; <br />
} <br /><br />
/** <br />
* 通过thin方式获得Oracle数据库的连接. <br />
* @param userId,password <br />
*/ <br />
public java.sql.Connection connectByJdbc(String userId,String password) <br />
{ <br />
java.sql.Connection conn=null; <br />
try <br />
{ <br />
Class.forName(sDBDriver); <br />
conn = DriverManager.getConnection(sConnStr,userId,password); <br />
} <br />
catch (Exception e) <br />
{ <br />
System.out.println("ERROR:"+e.getMessage()); <br />
} <br />
return conn; <br />
} <br />
} <br />
这种方式运用起来比较灵活，简单，具有较强的移植性和适用性。只要注意连接字符串"jdbc:oracle:thin:@10.1.4.199:1521:ora199"中具体参数的设置即可 <br /><br />
3、JdbcOdbc桥方式 <br /><br />
先通过管理工具中的数据源来添加本地对Oracle数据库的连接，然后通过以下的数据库连接类，在本地通过JdbcOdbc桥方式获得Oracle数据库连接。 <br /><br />
/** <br />
* 在本地获得数据库连接 <br />
*/ <br /><br />
package com.j2ee.db; <br /><br />
import java.util.*; <br />
import java.sql.*; <br />
import javax.sql.*; <br />
import java.io.*; <br />
import oracle.jdbc.driver.*; <br />
import javax.naming.*; <br /><br />
/** <br />
* 通过JdbcOdbc桥方式获得Oracle数据库连接 <br />
*/ <br />
public class DbConnection <br />
{ <br />
/** <br />
* <br />
*/ <br />
public DbConnection() <br />
{ <br />
} <br /><br />
/** <br />
* 获得Oracle数据库连接 <br />
*/ <br />
public java.sql.Connection connectDbByJdbcOdbcBridge() <br />
{ <br />
java.sql.Connection conn=null; <br />
try <br />
{ <br />
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); <br />
con=DriverManager.getConnection("jdbc:odbc:ora199","sr","sr"); <br />
} <br />
catch (Exception e) <br />
{ <br />
System.out.println("ERROR:"+e.getMessage()); <br />
} <br />
return conn; <br />
} <br />
} <br />
在getConnection方法中第一个参数"jdbc:odbc:ora199" 中的"ora199"为本地ODBC数据源的数据源名称，第二个参数和第三个参数分别为Oracle的用户名和口令。 <br /><br />
二、通过连接池获得Oracle数据库连接 <br /><br />
这部分主要讲述在iPlanet Application Server 6.5和Sun Java System Application Server 7中Oracle数据库连接池的配置，以及在应用中如何通过连接池获得数据库的连接。 <br /><br />
1、iPlanet Application Server 6.5连接池的配置 <br /><br />
先打开iPlanet Application Server 6.5的管理控制台，选中"database"面板，再选择"External
JDBC Drivers"选项后，点击"Add…"按钮，在弹出的对话框中，添加一个名为"ora-type4"的JDBC Driver。 <br /><br /><br />
Driver Classpath：该参数填写classes12.zip文件的物理路径。 <br /><br />
然后在"External JDBC DataSources"中选择"Add…"，在弹出的对话框中添加一个JNDI名称为"credit2"的数据源。 <br /><br /><br />
DriverType：选择刚添加好的"ora-type4"； <br /><br />
Datasource：ora199，为Oracle数据库服务名； <br /><br />
Datasource：ora199，为Oracle数据库服务名； <br /><br />
Connection Pool Parameters：图中显示的是缺省设置，可以根据自己环境情况来更改这些设置。 <br /><br />
保存完设置后，在"DataSource Selection Box"中，选择刚添加的"credit2"数据源，再选择"Vendor Specific Properties"按钮。在对话中添加一个URL属性。 <br /><br /><br />
至此，iPlanet Application Server 6.5中的数据库连接池配置完毕，重起服务使之生效。 <br /><br />
2、Sun Java System Application Server 7连接池的配置 <br /><br />
在配置之前将classes12.zip文件置于…/server1/lib目录下。通过浏览器的4848端口打开Sun Java System
Application Server 7的管理界面，选择"server1"-&gt;"JDBC"-&gt; "Connection
Pools"下的"New…" <br /><br /><br />
添加一个名称为"MyConnectionPool"的Oracle数据库连接池。"Next"下一步。 <br /><br /><br />
在"General"中填写"Datasource Classname"。 <br /><br /><br />
在"Properties"中将不需要的属性删除，同时添加"URL"属性。 <br /><br />
"dataSourceName"中填写Oracle数据库服务名。 <br /><br />
以下连接池的缺省设置，可以根据自己环境的情况作相应的调整。 <br /><br /><br />
选择"Finish"完成连接池的设置。 <br /><br />
下一步为"MyConnectionPool"连接池创建一个JNDI，以便应用程序能够通过该名称获得连接池中的连接。 "server1"-&gt;"JDBC"-&gt; "JDBC Resources"下的"New…" <br /><br /><br />
至此，Sun Java System Application Server7中的数据库连接池配置完毕，重起服务使之生效。 <br /><br />
3、通过连接池获得连接 <br /><br />
以上在iPlanet Application Server 6.5和Sun Java System Application Server7中配置的连接池都可以通过以下的数据库连接类，从连接池中获得Oracle数据库连接。 <br /><br />
/** <br />
* 从连接池中获得数据库连接 <br />
*/ <br /><br />
package com.j2ee.db; <br /><br />
import java.util.*; <br />
import java.sql.*; <br />
import javax.sql.*; <br />
import java.io.*; <br />
import oracle.jdbc.driver.*; <br />
import javax.naming.*; <br /><br />
/** <br />
* 通过连接池方式获得Oracle数据库连接 <br />
*/ <br />
public class DbConnection <br />
{ <br />
/** <br />
* <br />
*/ <br />
public DbConnection() <br />
{ <br />
} <br /><br />
/** <br />
* 获得Oracle数据库连接 <br />
*/ <br />
public java.sql.Connection connectDbByConnectionPool() <br />
{ <br />
java.sql.Connection conn=null; <br />
try <br />
{ <br />
Context ctx = new InitialContext(); <br />
DataSource ds = (DataSource)ctx.lookup("jdbc/credit2"); <br />
conn=ds.getConnection(); <br />
} <br />
catch (Exception e) <br />
{ <br />
System.out.println("ERROR:"+e.getMessage()); <br />
} <br />
return conn; <br />
} <br />
} <br />
4、使用连接池的优点使用连接池的优点主要体现在两个方面：对数据库的连接统一进行配置、管理、监控，以及对数据库连接池的参数进行优化调整，&lt;
br&gt;同时对应用中没有关闭或其他原因造成没有关闭的数据库连接由连接池统一进行管理。便于应用的移植和后端数据库的切换，&lt;br&gt;因
为在应用中通过统一的JNDI获得数据库的连接，而具体连接的是哪一台机器上的数据库与应用无关。</font>
<img src ="http://www.blogjava.net/hellotony/aggbug/49126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hellotony/" target="_blank">Tony</a> 2006-05-30 22:49 <a href="http://www.blogjava.net/hellotony/articles/49126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决Oracle监听器服务不能启动的问题(转)</title><link>http://www.blogjava.net/hellotony/articles/45747.html</link><dc:creator>Tony</dc:creator><author>Tony</author><pubDate>Thu, 11 May 2006 15:33:00 GMT</pubDate><guid>http://www.blogjava.net/hellotony/articles/45747.html</guid><wfw:comment>http://www.blogjava.net/hellotony/comments/45747.html</wfw:comment><comments>http://www.blogjava.net/hellotony/articles/45747.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hellotony/comments/commentRss/45747.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hellotony/services/trackbacks/45747.html</trackback:ping><description><![CDATA[
		<font size="2">从客户端连接到服务器,出现了这个错误,ora12541-TNS : 没有监听器
<br />于是,在服务器中启动OracleOraHome92TNSListener服务,显示“在本地计算机无法启动OracleOraHome92TNSListener服务，错误3，系统找不到指定路径”。
<br /><br />原因:Windows优化大师将Oracle的监听服务给"优化"了 
<br /><br />一、连接主机字符串，说没有监听器
<br />SVRMGR&gt; connect internal/oracle@orcl;
<br />ORA-12541: TNS:no listener
<br />SVRMGR&gt;
<br /><br />二、运行监听器，说地址的协议专用组件指定不正确
<br />C:\&gt;lsnrctl
<br />LSNRCTL for 32-bit Windows: Version 8.1.6.0.0 - Production on 14-3月 -2003 14:17
<br />:51
<br /><br />(c) Copyright 1998, 1999, Oracle Corporation. All rights reserved.
<br /><br />欢迎来到LSNRCTL，请键入"help"以获得信息。
<br /><br />LSNRCTL&gt; status
<br />连接至(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=robust)(PORT=1521)))
<br />TNS-01103: 地址的协议专用组件指定不正确
<br />TNS-12541: TNS：无监听器
<br />TNS-12560: TNS：协议适配器出现错误
<br />TNS-00511: 无监听器
<br />32-bit Windows Error: 61: Unknown error
<br /><br />LSNRCTL&gt; start
<br />启动tnslsnr：请稍候...
<br /><br />Failed to start service, error 3.
<br />TNS-12536: TNS：可能会阻碍*作
<br />TNS-12560: TNS：协议适配器出现错误
<br />TNS-00506: *作可能阻塞
<br />32-bit Windows Error: 997: Unknown error
<br /><br />LSNRCTL&gt;
<br /><br />三、在控制面板中启动服务，出现以下错误
<br />服务：在本地计算机 无法启动 OracleOraHome81TNSListener 服务。
<br />错误3：系统找不到指定的路径
<br /><br />而且OracleOraHome81TNSListener服务的可执行文件的路径是空的。
<br /><br />四、进入注册表中修改ImagePath
<br />在运行处执行REGEDIT进入注册表到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OracleOraHome81TNSListener
<br />发现ImagePath关键值没有了，增加他，选择可扩充字符串值，编辑字符串的数值数据为：f:\Oracle\Ora81\BIN\TNSLSNR 
<br />退出注册表。
<br /><br />五、再去启动服务，服务启动正常
<br /><br />六、启动监听器
<br />C:\&gt;lsnrctl
<br />LSNRCTL for 32-bit Windows: Version 8.1.6.0.0 - Production on 14-3月 -2003 14:42
<br />:10
<br />(c) Copyright 1998, 1999, Oracle Corporation. All rights reserved.
<br />欢迎来到LSNRCTL，请键入"help"以获得信息。
<br />LSNRCTL&gt; start
<br />TNS-01106: 使用名称LISTENER的监听器已经启动
<br />LSNRCTL&gt; status
<br />连接至(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=robust)(PORT=1521)))
<br />LISTENER 的 STATUS
<br />------------------------
<br />别名 LISTENER
<br />版本 TNSLSNR for 32-bit Windows: Version 8.1.6.0.0 - Produc
<br />tion
<br />启动日期 14-3月 -2003 14:40:15
<br />正常运行时间 0 天 0 小时 2 分 6 秒
<br />跟踪级别 off
<br />安全性 OFF
<br />SNMP OFF
<br />监听器参数文件 f:\Oracle\Ora81\network\admin\listener.ora
<br />监听器日志文件 f:\Oracle\Ora81\network\log\listener.log
<br />服务摘要..
<br />PLSExtProc 具有1个服务处理程序
<br />orc2 具有1个服务处理程序
<br />orcl 具有1个服务处理程序
<br />orcl 具有2个服务处理程序
<br />命令执行成功
<br />LSNRCTL&gt;
<br /><br />七、再去连接，成功
<br />SVRMGR&gt; connect internal/sys@orcl;
<br />连接成功。
<br />SVRMGR&gt;
</font>
<img src ="http://www.blogjava.net/hellotony/aggbug/45747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hellotony/" target="_blank">Tony</a> 2006-05-11 23:33 <a href="http://www.blogjava.net/hellotony/articles/45747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ORACLE常用命令</title><link>http://www.blogjava.net/hellotony/articles/40245.html</link><dc:creator>Tony</dc:creator><author>Tony</author><pubDate>Mon, 10 Apr 2006 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/hellotony/articles/40245.html</guid><wfw:comment>http://www.blogjava.net/hellotony/comments/40245.html</wfw:comment><comments>http://www.blogjava.net/hellotony/articles/40245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hellotony/comments/commentRss/40245.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hellotony/services/trackbacks/40245.html</trackback:ping><description><![CDATA[
		<font size="2">
				<span id="fontzoom">一、ORACLE的启动和关闭<br />1、在单机环境下<br />要想启动或关闭ORACLE系统必须首先切换到ORACLE用户，如下<br />su - oracle<br /><br />a、启动ORACLE系统<br />oracle&gt;svrmgrl<br />SVRMGR&gt;connect internal<br />SVRMGR&gt;startup<br />SVRMGR&gt;quit<br /><br />b、关闭ORACLE系统<br />oracle&gt;svrmgrl<br />SVRMGR&gt;connect internal<br />SVRMGR&gt;shutdown<br />SVRMGR&gt;quit<br /><br />启动oracle9i数据库命令：<br />$ sqlplus /nolog<br /><br />SQL*Plus: Release 9.2.0.1.0 - Production on Fri Oct 31 13:53:53 2003<br /><br />Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.<br /><br />SQL&gt; connect / as sysdba  <br />Connected to an idle instance.<br />SQL&gt; startup^C<br /><br />SQL&gt; startup<br />ORACLE instance started.<br /><br /><br />2、在双机环境下<br />要想启动或关闭ORACLE系统必须首先切换到root用户，如下<br />su － root<br /><br />a、启动ORACLE系统<br />hareg －y oracle<br /><br />b、关闭ORACLE系统<br />hareg －n oracle<br /><br />Oracle数据库有哪几种启动方式<br /><br /><br />说明：<br /><br />有以下几种启动方式：<br />1、startup nomount<br />非安装启动，这种方式启动下可执行：重建控制文件、重建数据库<br /><br />读取init.ora文件，启动instance，即启动SGA和后台进程，这种启动只需要init.ora文件。<br /><br /><br />2、startup mount dbname<br />安装启动，这种方式启动下可执行：<br />数据库日志归档、<br />数据库介质恢复、<br />使数据文件联机或脱机，<br />重新定位数据文件、重做日志文件。<br /><br />执行“nomount”，然后打开控制文件，确认数据文件和联机日志文件的位置，<br />但此时不对数据文件和日志文件进行校验检查。<br /><br /><br />3、startup open dbname<br />先执行“nomount”，然后执行“mount”，再打开包括Redo log文件在内的所有数据库文件，<br />这种方式下可访问数据库中的数据。<br /><br /><br />4、startup，等于以下三个命令<br />startup nomount<br />alter database mount<br />alter database open<br /><br /><br />5、startup restrict<br />约束方式启动<br />这种方式能够启动数据库，但只允许具有一定特权的用户访问<br />非特权用户访问时，会出现以下提示：<br />ERROR：<br />ORA-01035: ORACLE 只允许具有 RESTRICTED SESSION 权限的用户使用<br /><br /><br />6、startup force<br />强制启动方式<br />当不能关闭数据库时，可以用startup force来完成数据库的关闭<br />先关闭数据库，再执行正常启动数据库命令<br /><br /><br />7、startup pfile=参数文件名<br />带初始化参数文件的启动方式<br />先读取参数文件，再按参数文件中的设置启动数据库<br />例：startup pfile=E:Oracleadminoradbpfileinit.ora<br /><br /><br />8、startup EXCLUSIVE<br />二、用户如何有效地利用数据字典<br />  　ORACLE的数据字典是数据库的重要组成部分之一，它随着数据库的产生而产生, 随着数据库的变化而变化,<br />体现为sys用户下的一些表和视图。数据字典名称是大写的英文字符。<br /><br />    数据字典里存有用户信息、用户的权限信息、所有数据对象信息、表的约束条件、统计分析数据库的视图等。<br />我们不能手工修改数据字典里的信息。<br /><br />　　很多时候，一般的ORACLE用户不知道如何有效地利用它。<br /><br />　　dictionary　　　全部数据字典表的名称和解释，它有一个同义词dict<br />    dict_column　　 全部数据字典表里字段名称和解释<br /><br />    如果我们想查询跟索引有关的数据字典时，可以用下面这条SQL语句:<br /><br />    SQL&gt;select * from dictionary where instr(comments,'index')&gt;0;<br /><br />    如果我们想知道user_indexes表各字段名称的详细含义，可以用下面这条SQL语句:<br /><br />    SQL&gt;select column_name,comments from dict_columns where table_name='USER_INDEXES';<br /><br />    依此类推，就可以轻松知道数据字典的详细名称和解释，不用查看ORACLE的其它文档资料了。<br /><br />    下面按类别列出一些ORACLE用户常用数据字典的查询使用方法。<br /><br />    1、用户<br /><br />            查看当前用户的缺省表空间<br />            SQL&gt;select username,default_tablespace from user_users;<br /><br />        查看当前用户的角色<br />        SQL&gt;select * from user_role_privs;<br /><br />        查看当前用户的系统权限和表级权限<br />        SQL&gt;select * from user_sys_privs;<br />        SQL&gt;select * from user_tab_privs;<br /><br />    2、表<br /><br />            查看用户下所有的表<br />            SQL&gt;select * from user_tables;<br /><br />            查看名称包含log字符的表<br />            SQL&gt;select object_name,object_id from user_objects<br />                where instr(object_name,'LOG')&gt;0;<br /><br />            查看某表的创建时间<br />            SQL&gt;select object_name,created from user_objects where object_name=upper('&amp;table_name');<br /><br />            查看某表的大小<br />            SQL&gt;select sum(bytes)/(1024*1024) as "size(M)" from user_segments<br />                where segment_name=upper('&amp;table_name');<br /><br />            查看放在ORACLE的内存区里的表<br />            SQL&gt;select table_name,cache from user_tables where instr(cache,'Y')&gt;0;<br /><br />    3、索引<br /><br />            查看索引个数和类别<br />            SQL&gt;select index_name,index_type,table_name from user_indexes order by table_name;<br /><br />            查看索引被索引的字段<br />            SQL&gt;select * from user_ind_columns where index_name=upper('&amp;index_name');<br /><br />            查看索引的大小<br />            SQL&gt;select sum(bytes)/(1024*1024) as "size(M)" from user_segments<br />                where segment_name=upper('&amp;index_name');<br /><br />    4、序列号<br /><br />            查看序列号，last_number是当前值<br />            SQL&gt;select * from user_sequences;<br /><br />    5、视图<br /><br />            查看视图的名称<br />            SQL&gt;select view_name from user_views;<br /><br />            查看创建视图的select语句<br />            SQL&gt;set view_name,text_length from user_views;<br />            SQL&gt;set long 2000;                说明：可以根据视图的text_length值设定set long 的大小<br />            SQL&gt;select text from user_views where view_name=upper('&amp;view_name');<br /><br />    6、同义词<br /><br />            查看同义词的名称<br />            SQL&gt;select * from user_synonyms;<br /><br />    7、约束条件<br /><br />            查看某表的约束条件<br />            SQL&gt;select constraint_name, constraint_type,search_condition, r_constraint_name<br />                from user_constraints where table_name = upper('&amp;table_name');<br /><br />        SQL&gt;select c.constraint_name,c.constraint_type,cc.column_name<br />            from user_constraints c,user_cons_columns cc<br />            where c.owner = upper('&amp;table_owner') and c.table_name = upper('&amp;table_name')<br />            and c.owner = cc.owner and c.constraint_name = cc.constraint_name<br />            order by cc.position;<br /><br />    8、存储函数和过程<br /><br />            查看函数和过程的状态<br />            SQL&gt;select object_name,status from user_objects where object_type='FUNCTION';<br />            SQL&gt;select object_name,status from user_objects where object_type='PROCEDURE';<br /><br />            查看函数和过程的源代码<br />            SQL&gt;select text from all_source where owner=user and name=upper('&amp;plsql_name');<br /><br /><br />三、查看数据库的SQL<br />1、查看表空间的名称及大小<br /><br />    select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size<br />    from dba_tablespaces t, dba_data_files d<br />    where t.tablespace_name = d.tablespace_name<br />    group by t.tablespace_name;<br /><br />2、查看表空间物理文件的名称及大小<br /><br />    select tablespace_name, file_id, file_name,<br />    round(bytes/(1024*1024),0) total_space<br />    from dba_data_files<br />    order by tablespace_name;<br /><br />3、查看回滚段名称及大小<br /><br />    select segment_name, tablespace_name, r.status,<br />    (initial_extent/1024) InitialExtent,(next_extent/1024) NextExtent,<br />    max_extents, v.curext CurExtent<br />    From dba_rollback_segs r, v$rollstat v<br />    Where r.segment_id = v.usn(+)<br />    order by segment_name ;<br /><br />4、查看控制文件<br /><br />    select name from v$controlfile;<br /><br />5、查看日志文件<br /><br />    select member from v$logfile;<br /><br />6、查看表空间的使用情况<br /><br />    select sum(bytes)/(1024*1024) as free_space,tablespace_name<br />    from dba_free_space<br />    group by tablespace_name;<br /><br />    SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE,<br />    (B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE"<br />    FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C<br />    WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME;<br /><br />7、查看数据库库对象<br /><br />    select owner, object_type, status, count(*) count# from all_objects group by owner, object_type, status;<br /><br />8、查看数据库的版本<br /><br />    Select version FROM Product_component_version<br />    Where SUBSTR(PRODUCT,1,6)='Oracle';<br /><br />9、查看数据库的创建日期和归档方式<br /><br />    Select Created, Log_Mode, Log_Mode From V$Database;<br />四、ORACLE用户连接的管理<br /><br />用系统管理员，查看当前数据库有几个用户连接：<br /><br />SQL&gt; select username,sid,serial# from v$session;<br /><br />如果要停某个连接用<br /><br />SQL&gt; alter system kill session 'sid,serial#';<br /><br />如果这命令不行,找它UNIX的进程数<br /><br />SQL&gt; select pro.spid from v$session ses,v$process pro where ses.sid=21 and ses.paddr=pro.addr;<br /><br />说明：21是某个连接的sid数<br /><br />然后用 kill 命令杀此进程号。<br /><br /><br />五、SQL*PLUS使用<br />a、近入SQL*Plus<br />$sqlplus 用户名/密码<br /><br />   退出SQL*Plus<br />SQL&gt;exit<br /><br />b、在sqlplus下得到帮助信息<br />列出全部SQL命令和SQL*Plus命令<br />SQL&gt;help<br />列出某个特定的命令的信息<br />SQL&gt;help 命令名<br /><br />c、显示表结构命令DESCRIBE<br />SQL&gt;DESC 表名<br /><br />d、SQL*Plus中的编辑命令<br />显示SQL缓冲区命令<br />SQL&gt;L<br /><br />修改SQL命令<br />首先要将待改正行变为当前行<br />SQL&gt;n<br />用CHANGE命令修改内容<br />SQL&gt;c/旧/新<br />重新确认是否已正确<br />SQL&gt;L<br /><br />使用INPUT命令可以在SQL缓冲区中增加一行或多行<br />SQL&gt;i<br />SQL&gt;输入内容<br /><br />e、调用外部系统编辑器<br />SQL&gt;edit 文件名<br />可以使用DEFINE命令设置系统变量EDITOR来改变文本编辑器的类型，在login.sql文件中定义如下一行<br />DEFINE_EDITOR=vi<br /><br />f、运行命令文件<br />SQL&gt;START test<br />SQL&gt;@test<br /><br />常用SQL*Plus语句<br />a、表的创建、修改、删除<br />创建表的命令格式如下：<br />create table 表名 （列说明列表）；<br /><br />为基表增加新列命令如下：<br />ALTER TABLE 表名 ADD （列说明列表）<br />例：为test表增加一列Age，用来存放年龄<br />    sql&gt;alter table test<br />        add （Age number(3)）；<br /><br />修改基表列定义命令如下：<br />ALTER TABLE 表名<br />MODIFY （列名 数据类型）<br />例：将test表中的Count列宽度加长为10个字符<br />    sql&gt;alter atble test<br />        modify （County char(10)）；<br /><br />b、将一张表删除语句的格式如下：<br />DORP TABLE 表名；<br />例：表删除将同时删除表的数据和表的定义<br />sql&gt;drop table test<br /><br />c、表空间的创建、删除<br /><br /><br />六、ORACLE逻辑备份的SH文件<br /><br />完全备份的SH文件：exp_comp.sh<br /><br />rq=` date +"%m%d" `<br /><br />su - oracle -c "exp system/manager full=y inctype=complete file=/oracle/export/db_comp$rq.dmp"<br /><br />累计备份的SH文件：exp_cumu.sh<br /><br />rq=` date +"%m%d" `<br /><br />su - oracle -c "exp system/manager full=y inctype=cumulative file=/oracle/export/db_cumu$rq.dmp"<br /><br />增量备份的SH文件: exp_incr.sh<br /><br />rq=` date +"%m%d" `<br /><br />su - oracle -c "exp system/manager full=y inctype=incremental file=/oracle/export/db_incr$rq.dmp"<br /><br />root用户crontab文件<br />/var/spool/cron/crontabs/root增加以下内容<br /><br />0 2 1 * * /oracle/exp_comp.sh<br /><br />30 2 * * 0-5 /oracle/exp_incr.sh<br /><br />45 2 * * 6 /oracle/exp_cumu.sh<br /><br />当然这个时间表可以根据不同的需求来改变的，这只是一个例子。<br /><br /><br />七、ORACLE 常用的SQL语法和数据对象<br /><br />一.数据控制语句 (DML) 部分<br /><br />1.INSERT  (往数据表里插入记录的语句)<br /><br />INSERT INTO 表名(字段名1, 字段名2, ……) VALUES ( 值1, 值2, ……);<br />INSERT INTO 表名(字段名1, 字段名2, ……)  SELECT (字段名1, 字段名2, ……) FROM 另外的表名;<br /><br />字符串类型的字段值必须用单引号括起来, 例如: ’GOOD DAY’<br />如果字段值里包含单引号’ 需要进行字符串转换, 我们把它替换成两个单引号''.<br />字符串类型的字段值超过定义的长度会出错, 最好在插入前进行长度校验.<br /><br />日期字段的字段值可以用当前数据库的系统时间SYSDATE, 精确到秒<br />或者用字符串转换成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)<br />TO_DATE()还有很多种日期格式, 可以参看ORACLE DOC.<br />年-月-日 小时:分钟:秒 的格式YYYY-MM-DD HH24:MI:SS<br /><br />INSERT时最大可操作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型,<br />方法借用ORACLE里自带的DBMS_LOB程序包.<br /><br />INSERT时如果要用到从1开始自动增长的序列号, 应该先建立一个序列号<br />CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1  START  WITH  1<br />MAXVALUE  99999  CYCLE  NOCACHE;<br />其中最大的值按字段的长度来定, 如果定义的自动增长的序列号 NUMBER(6) , 最大值为999999<br />INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL<br /><br />2.DELETE  (删除数据表里记录的语句)<br /><br />DELETE FROM表名 WHERE 条件;<br /><br />注意：删除记录并不能释放ORACLE里被占用的数据块表空间. 它只把那些被删除的数据块标成unused.<br /><br />如果确实要删除一个大表里的全部记录, 可以用 TRUNCATE 命令, 它可以释放占用的数据块表空间<br />TRUNCATE TABLE 表名;<br />此操作不可回退.<br /><br />3.UPDATE  (修改数据表里记录的语句)<br /><br />UPDATE表名 SET 字段名1=值1, 字段名2=值2, …… WHERE 条件;<br /><br />如果修改的值N没有赋值或定义时, 将把原来的记录内容清为NULL, 最好在修改前进行非空校验;<br />值N超过定义的长度会出错, 最好在插入前进行长度校验..<br /><br />注意事项:<br />A.        以上SQL语句对表都加上了行级锁,<br />        确认完成后, 必须加上事物处理结束的命令 COMMIT 才能正式生效,<br />        否则改变不一定写入数据库里.<br />        如果想撤回这些操作, 可以用命令 ROLLBACK 复原.<br /><br />B.        在运行INSERT, DELETE 和 UPDATE 语句前最好估算一下可能操作的记录范围,<br />        应该把它限定在较小 (一万条记录) 范围内,. 否则ORACLE处理这个事物用到很大的回退段.<br />        程序响应慢甚至失去响应. 如果记录数上十万以上这些操作, 可以把这些SQL语句分段分次完成,<br />        其间加上COMMIT 确认事物处理.<br />二.数据定义 (DDL) 部分<br /><br />1.CREATE (创建表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)<br /><br />ORACLE常用的字段类型有<br />CHAR                        固定长度的字符串<br />VARCHAR2                可变长度的字符串<br />NUMBER(M,N)                数字型M是位数总长度, N是小数的长度<br />DATE                        日期类型<br /><br />创建表时要把较小的不为空的字段放在前面, 可能为空的字段放在后面<br /><br />创建表时可以用中文的字段名, 但最好还是用英文的字段名<br /><br />创建表时可以给字段加上默认值, 例如 DEFAULT SYSDATE<br />这样每次插入和修改时, 不用程序操作这个字段都能得到动作的时间<br /><br />创建表时可以给字段加上约束条件<br />例如 不允许重复 UNIQUE, 关键字 PRIMARY KEY<br /><br />2.ALTER        (改变表, 索引, 视图等)<br /><br />改变表的名称<br />ALTER TABLE 表名1  TO 表名2;<br /><br />在表的后面增加一个字段<br />ALTER TABLE表名 ADD 字段名 字段名描述;<br /><br />修改表里字段的定义描述<br />ALTER TABLE表名 MODIFY字段名 字段名描述;<br /><br />给表里的字段加上约束条件<br />ALTER TABLE 表名 ADD CONSTRAINT 约束名 PRIMARY KEY (字段名);<br />ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE (字段名);<br /><br />把表放在或取出数据库的内存区<br />ALTER TABLE 表名 CACHE;<br />ALTER TABLE 表名 NOCACHE;<br /><br />3.DROP        (删除表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)<br /><br />删除表和它所有的约束条件<br />DROP TABLE 表名 CASCADE CONSTRAINTS;<br /><br />4.TRUNCATE (清空表里的所有记录, 保留表的结构)<br /><br />TRUNCATE 表名;<br /><br />三.查询语句 (SELECT) 部分<br /><br />SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE 条件;<br /><br />字段名可以带入函数<br />  例如:  COUNT(*), MIN(字段名),  MAX(字段名),  AVG(字段名), DISTINCT(字段名),<br />           TO_CHAR(DATE字段名,'YYYY-MM-DD HH24:MI:SS')<br /><br />NVL(EXPR1, EXPR2)函数<br />解释:<br />IF EXPR1=NULL<br />                RETURN EXPR2<br />ELSE<br />                       RETURN EXPR1<br /><br />DECODE(AA﹐V1﹐R1﹐V2﹐R2....)函数<br />解释:<br />IF AA=V1 THEN RETURN R1<br />IF AA=V2 THEN RETURN R2<br />..…<br />ELSE<br />RETURN NULL<br /><br />LPAD(char1,n,char2)函数<br />解释:<br />字符char1按制定的位数n显示，不足的位数用char2字符串替换左边的空位<br /><br />字段名之间可以进行算术运算<br />例如:  (字段名1*字段名1)/3<br /><br />查询语句可以嵌套<br />例如: SELECT …… FROM<br />(SELECT …… FROM表名1, [表名2, ……] WHERE 条件) WHERE 条件2;<br /><br />两个查询语句的结果可以做集合操作<br />例如: 并集UNION(去掉重复记录), 并集UNION ALL(不去掉重复记录), 差集MINUS,  交集INTERSECT<br /><br />分组查询<br />SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] GROUP BY字段名1<br />[HAVING 条件] ;<br /><br />两个以上表之间的连接查询<br /><br />SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE<br />                表名1.字段名 = 表名2. 字段名 [ AND ……] ;<br /><br />SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE<br />                表名1.字段名 = 表名2. 字段名(+) [ AND ……] ;<br /><br />有(+)号的字段位置自动补空值<br /><br />查询结果集的排序操作, 默认的排序是升序ASC, 降序是DESC<br /><br />SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……]<br />ORDER BY字段名1, 字段名2 DESC;<br /><br />字符串模糊比较的方法<br /><br />INSTR(字段名, ‘字符串’)&gt;0<br />字段名 LIKE  ‘字符串%’  [‘%字符串%’]<br /><br />每个表都有一个隐含的字段ROWID, 它标记着记录的唯一性.<br /><br />四.ORACLE里常用的数据对象 (SCHEMA)<br /><br />1.索引 (INDEX)<br /><br />CREATE INDEX 索引名ON 表名 ( 字段1, [字段2, ……] );<br />ALTER INDEX 索引名 REBUILD;<br /><br />一个表的索引最好不要超过三个 (特殊的大表除外), 最好用单字段索引, 结合SQL语句的分析执行情况,<br />也可以建立多字段的组合索引和基于函数的索引<br /><br />ORACLE8.1.7字符串可以索引的最大长度为1578 单字节<br />ORACLE8.0.6字符串可以索引的最大长度为758 单字节<br /><br />2.视图 (VIEW)<br /><br />CREATE VIEW 视图名AS SELECT …. FROM …..;<br />ALTER VIEW视图名 COMPILE;<br /><br />视图仅是一个SQL查询语句, 它可以把表之间复杂的关系简洁化.<br /><br />3.同义词 (SYNONMY)<br />CREATE SYNONYM同义词名FOR 表名;<br />CREATE SYNONYM同义词名FOR 表名@数据库链接名;<br /><br />4.数据库链接 (DATABASE LINK)<br />CREATE DATABASE LINK数据库链接名CONNECT TO 用户名 IDENTIFIED BY 密码 USING ‘数据库连接字符串’;<br /><br />数据库连接字符串可以用NET8 EASY CONFIG或者直接修改TNSNAMES.ORA里定义.<br /><br />数据库参数global_name=true时要求数据库链接名称跟远端数据库名称一样<br /><br />数据库全局名称可以用以下命令查出<br />SELECT * FROM GLOBAL_NAME;<br /><br />查询远端数据库里的表<br />SELECT …… FROM 表名@数据库链接名;<br /><br />五.权限管理 (DCL) 语句<br /><br />1.GRANT        赋于权限<br />常用的系统权限集合有以下三个:<br />CONNECT(基本的连接), RESOURCE(程序开发), DBA(数据库管理)<br />常用的数据对象权限有以下五个:<br />ALL         ON 数据对象名,         SELECT ON 数据对象名,         UPDATE ON 数据对象名,<br />DELETE         ON 数据对象名,  INSERT ON 数据对象名,   ALTER  ON 数据对象名<br /><br />GRANT CONNECT, RESOURCE TO 用户名;<br />GRANT SELECT ON 表名 TO 用户名;<br />GRANT SELECT, INSERT, DELETE ON表名 TO 用户名1, 用户名2;<br /><br />2.REVOKE 回收权限<br /><br />REVOKE CONNECT, RESOURCE FROM 用户名;<br />REVOKE SELECT ON 表名 FROM 用户名;<br />REVOKE SELECT, INSERT, DELETE ON表名 FROM 用户名1, 用户名2;<br /><br /><br />查询数据库中第63号错误：<br />select orgaddr,destaddr from sm_histable0116 where error_code='63';<br /><br />查询数据库中开户用户最大提交和最大下发数： select MSISDN,TCOS,OCOS from ms_usertable；<br /><br /><br />查询数据库中各种错误代码的总和：<br />select error_code,count(*) from sm_histable0513 group by error_code order<br />by error_code;<br /><br />查询报表数据库中话单统计种类查询。<br />select sum(Successcount) from tbl_MiddleMt0411 where ServiceType2=111<br />select sum(successcount),servicetype from tbl_middlemt0411 group by servicetype<br /></span>
		</font>
<img src ="http://www.blogjava.net/hellotony/aggbug/40245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hellotony/" target="_blank">Tony</a> 2006-04-10 15:44 <a href="http://www.blogjava.net/hellotony/articles/40245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于ORACLE连接池</title><link>http://www.blogjava.net/hellotony/articles/29266.html</link><dc:creator>Tony</dc:creator><author>Tony</author><pubDate>Thu, 26 Jan 2006 09:52:00 GMT</pubDate><guid>http://www.blogjava.net/hellotony/articles/29266.html</guid><wfw:comment>http://www.blogjava.net/hellotony/comments/29266.html</wfw:comment><comments>http://www.blogjava.net/hellotony/articles/29266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hellotony/comments/commentRss/29266.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hellotony/services/trackbacks/29266.html</trackback:ping><description><![CDATA[<font size="2">
              到目前为目,JDBC2的连结池只是一个接口,没有真正的实现,JDBC3正在开发中,据报已经支持连结池,但JDBC3用了JNDI技术,连结池的配置可以让一个高手都烦死. </font>
              <p><font size="2">目前第三方已经实现的连结池当然是poolman,1.0版对一般用户来说已经足够用了.配置也简单,2.0版虽然增加了一些功能,但配置也是采用JNDI,对RMI和EJB不懂的朋友可能很烦.建议用1.0的了. </font></p>
              <p><font size="2">如果有兴趣,自己也可以实现连结池,最关键的技术也就是把连结作为参数传给一个BEAN,用完后返回这个参数连结而不是关闭. <br>
                下面是一个简单的实现: <br>
                DBConnectionManager.java程序清单如下： </font></p>
              <p><font size="2">001 import java.io.*; <br>
                002 import java.sql.*; <br>
                003 import java.util.*; <br>
                004 import java.util.Date; <br>
                005 <br>
                006 /** <br>
                007 * 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接 <br>
                008 * 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例. <br>
                009 */ <br>
                010 public class DBConnectionManager { <br>
                011 static private DBConnectionManager instance; // 唯一实例 <br>
                012 static private int clients; <br>
                013 <br>
                014 private Vector drivers = new Vector(); <br>
                015 private PrintWriter log; <br>
                016 private Hashtable pools = new Hashtable(); <br>
                017 <br>
                018 /** <br>
                019 * 返回唯一实例.如果是第一次调用此方法,则创建实例 <br>
                020 * <br>
                021 * @return DBConnectionManager 唯一实例 <br>
                022 */ <br>
                023 static synchronized public DBConnectionManager getInstance() { <br>
                024 if (instance == null) { <br>
                025 instance = new DBConnectionManager(); <br>
                026 } <br>
                027 clients++; <br>
                028 return instance; <br>
                029 } <br>
                030 <br>
                031 /** <br>
                032 * 建构函数私有以防止其它对象创建本类实例 <br>
                033 */ <br>
                034 private DBConnectionManager() { <br>
                035 init(); <br>
                036 } <br>
                037 <br>
                038 /** <br>
                039 * 将连接对象返回给由名字指定的连接池 <br>
                040 * <br>
                041 * @param name 在属性文件中定义的连接池名字 <br>
                042 * @param con 连接对象\\r </font></p>
              <p><font size="2">043 */ <br>
                044 public void freeConnection(String name, Connection con) { <br>
                045 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br>
                046 if (pool != null) { <br>
                047 pool.freeConnection(con); <br>
                048 } <br>
                049 } <br>
                050 <br>
                051 /** <br>
                052 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数 <br>
                053 * 限制,则创建并返回新连接 <br>
                054 * <br>
                055 * @param name 在属性文件中定义的连接池名字 <br>
                056 * @return Connection 可用连接或null <br>
                057 */ <br>
                058 public Connection getConnection(String name) { <br>
                059 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br>
                060 if (pool != null) { <br>
                061 return pool.getConnection(); <br>
                062 } <br>
                063 return null; <br>
                064 } <br>
                065 <br>
                066 /** <br>
                067 * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制, <br>
                068 * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接. <br>
                069 * <br>
                070 * @param name 连接池名字 <br>
                071 * @param time 以毫秒计的等待时间\\r </font></p>
              <p><font size="2">072 * @return Connection 可用连接或null <br>
                073 */ <br>
                074 public Connection getConnection(String name, long time) { <br>
                075 DBConnectionPool pool = (DBConnectionPool) pools.get(name); <br>
                076 if (pool != null) { <br>
                077 return pool.getConnection(time); <br>
                078 } <br>
                079 return null; <br>
                080 } <br>
                081 <br>
                082 /** <br>
                083 * 关闭所有连接,撤销驱动程序的注册\\r </font></p>
              <p><font size="2">084 */ <br>
                085 public synchronized void release() { <br>
                086 // 等待直到最后一个客户程序调用 <br>
                087 if (--clients != 0) { <br>
                088 return; <br>
                089 } <br>
                090 <br>
                091 Enumeration allPools = pools.elements(); <br>
                092 while (allPools.hasMoreElements()) { <br>
                093 DBConnectionPool pool = (DBConnectionPool</font></p>
              <p><font size="2">) allPools.nextElement(); <br>
                094 pool.release(); <br>
                095 } <br>
                096 Enumeration allDrivers = drivers.elements(); <br>
                097 while (allDrivers.hasMoreElements()) { <br>
                098 Driver driver = (Driver) allDrivers.nextElement(); <br>
                099 try { <br>
                100 DriverManager.deregisterDriver(driver); <br>
                101 log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册\\\"); <br>
                102 } <br>
                103 catch (SQLException e) { <br>
                104 log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName()); <br>
                105 } <br>
                106 } <br>
                107 } <br>
                108 <br>
                109 /** <br>
                110 * 根据指定属性创建连接池实例. <br>
                111 * <br>
                112 * @param props 连接池属性 <br>
                113 */ <br>
                114 private void createPools(Properties props) { <br>
                115 Enumeration propNames = props.propertyNames(); <br>
                116 while (propNames.hasMoreElements()) { <br>
                117 String name = (String) propNames.nextElement(); <br>
                118 if (name.endsWith(".url")) { <br>
                119 String poolName = name.substring(0, name.lastIndexOf(".")); <br>
                120 String url = props.getProperty(poolName + ".url"); <br>
                121 if (url == null) { <br>
                122 log("没有为连接池" + poolName + "指定URL"); <br>
                123 continue; <br>
                124 } <br>
                125 String user = props.getProperty(poolName + ".user"); <br>
                126 String password = props.getProperty(poolName + ".password"); <br>
                127 String maxconn = props.getProperty(poolName + ".maxconn", "0"); <br>
                128 int max; <br>
                129 try { <br>
                130 max = Integer.valueOf(maxconn).intValue(); <br>
                131 } <br>
                132 catch (NumberFormatException e) { <br>
                133 log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName); <br>
                134 max = 0; <br>
                135 } <br>
                136 DBConnectionPool pool = <br>
                137 new DBConnectionPool(poolName, url, user, password, max); <br>
                138 pools.put(poolName, pool); <br>
                139 log("成功创建连接池" + poolName); <br>
                140 } <br>
                141 } <br>
                142 } <br>
                143 <br>
                144 /** <br>
                145 * 读取属性完成初始化 <br>
                146 */ <br>
                147 private void init() { <br>
                148 InputStream is = getClass().getResourceAsStream("/db.properties"); <br>
                149 Properties dbProps = new Properties(); <br>
                150 try { <br>
                151 dbProps.load(is); <br>
                152 } <br>
                153 catch (Exception e) { <br>
                154 System.err.println("不能读取属性文件. " + <br>
                155 "请确保db.properties在CLASSPATH指定的路径中"); <br>
                156 return; <br>
                157 } <br>
                158 String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log"); <br>
                159 try { <br>
                160 log = new PrintWriter(new FileWriter(logFile, true), true); <br>
                161 } <br>
                162 catch (IOException e) { <br>
                163 System.err.println("无法打开日志文件: " + logFile); <br>
                164 log = new PrintWriter(System.err); <br>
                165 } <br>
                166 loadDrivers(dbProps); <br>
                167 createPools(dbProps); <br>
                168 } <br>
                169 <br>
                170 /** <br>
                171 * 装载和注册所有JDBC驱动程序\\r </font></p>
              <p><font size="2">172 * <br>
                173 * @param props 属性 <br>
                174 */ <br>
                175 private void loadDrivers(Properties props) { <br>
                176 String driverClasses = props.getProperty("drivers"); <br>
                177 StringTokenizer st = new StringTokenizer(driverClasses); <br>
                178 while (st.hasMoreElements()) { <br>
                179 String driverClassName = st.nextToken().trim(); <br>
                180 try { <br>
                181 Driver driver = (Driver) <br>
                182 Class.forName(driverClassName).newInstance(); <br>
                183 DriverManager.registerDr</font></p><font size="2">
              iver(driver); <br>
              184 drivers.addElement(driver); <br>
              185 log("成功注册JDBC驱动程序\\\" + driverClassName); <br>
              186 } <br>
              187 catch (Exception e) { <br>
              188 log("无法注册JDBC驱动程序: " + <br>
              189 driverClassName + ", 错误: " + e); <br>
              190 } <br>
              191 } <br>
              192 } <br>
              193 <br>
              194 /** <br>
              195 * 将文本信息写入日志文件 <br>
              196 */ <br>
              197 private void log(String msg) { <br>
              198 log.println(new Date() + ": " + msg); <br>
              199 } <br>
              200 <br>
              201 /** <br>
              202 * 将文本信息与异常写入日志文件 <br>
              203 */ <br>
              204 private void log(Throwable e, String msg) { <br>
              205 log.println(new Date() + ": " + msg); <br>
              206 e.printStackTrace(log); <br>
              207 } <br>
              208 <br>
              209 /** <br>
              210 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最\\r
              </font><p><font size="2">211 * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性. <br>
                212 */ <br>
                213 class DBConnectionPool { <br>
                214 private int checkedOut; <br>
                215 private Vector freeConnections = new Vector(); <br>
                216 private int maxConn; <br>
                217 private String name; <br>
                218 private String password; <br>
                219 private String URL; <br>
                220 private String user; <br>
                221 <br>
                222 /** <br>
                223 * 创建新的连接池 <br>
                224 * <br>
                225 * @param name 连接池名字 <br>
                226 * @param URL 数据库的JDBC URL <br>
                227 * @param user 数据库帐号,或 null <br>
                228 * @param password 密码,或 null <br>
                229 * @param maxConn 此连接池允许建立的最大连接数 <br>
                230 */ <br>
                231 public DBConnectionPool(String name, String URL, String user, String password, <br>
                232 int maxConn) { <br>
                233 this.name = name; <br>
                234 this.URL = URL; <br>
                235 this.user = user; <br>
                236 this.password = password; <br>
                237 this.maxConn = maxConn; <br>
                238 } <br>
                239 <br>
                240 /** <br>
                241 * 将不再使用的连接返回给连接池 <br>
                242 * <br>
                243 * @param con 客户程序释放的连接 <br>
                244 */ <br>
                245 public synchronized void freeConnection(Connection con) { <br>
                246 // 将指定连接加入到向量末尾 <br>
                247 freeConnections.addElement(con); <br>
                248 checkedOut--; <br>
                249 notifyAll(); <br>
                250 } <br>
                251 <br>
                252 /** <br>
                253 * 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接 <br>
                254 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之, <br>
                255 * 然后递归调用自己以尝试新的可用连接. <br>
                256 */ <br>
                257 public synchronized Connection getConnection() { <br>
                258 Connection con = null; <br>
                259 if (freeConnections.size() > 0) { <br>
                260 // 获取向量中第一个可用连接 <br>
                261 con = (Connection) freeConnections.firstElement(); <br>
                262 freeConnections.removeElementAt(0); <br>
                263 try { <br>
                264 if (con.isClosed()) { <br>
                265 log("从连接池" + name+"删除一个无效连接"); <br>
                266 // 递归调用自己,尝试再次获取可用连接 <br>
                267 con = getConnection(); <br>
                268 } <br>
                269 } <br>
                270 catch (SQLException e) { <br>
                271 log("从连接池" + name+"删除一个无效连接"); <br>
                272 // 递归调用自己,尝试再次获取可用连接 <br>
                273 con = getConnection(); <br>
                274 } <br>
                275 } <br>
                276 else if (maxConn == 0 || checkedOut < maxConn) { <br>
                277 con = newConnection(); <br>
                278 } <br>
                279 if (con != null) { <br>
                280 checkedOut++; <br>
                281 } <br>
                282 return con; <br>
                283 } <br>
                284 <br>
                285 /** <br>
                286 * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间\\r </font></p>
              <p><font size="2">287 * 参见前一个getConnection()方法. <br>
                288 * <br>
                289 * @param timeout 以毫秒计的等待时间限制 <br>
                290 */ <br>
                291 public synchronized Connection getConnection(long timeout) { <br>
                292 long startTime = new Date().getTime();</font></p><font size="2">
              293 Connection con; <br>
              294 while ((con = getConnection()) == null) { <br>
              295 try { <br>
              296 wait(timeout); <br>
              297 } <br>
              298 catch (InterruptedException e) {} <br>
              299 if ((new Date().getTime() - startTime) >= timeout) { <br>
              300 // wait()返回的原因是超时 <br>
              301 return null; <br>
              302 } <br>
              303 } <br>
              304 return con; <br>
              305 } <br>
              306 <br>
              307 /** <br>
              308 * 关闭所有连接 <br>
              309 */ <br>
              310 public synchronized void release() { <br>
              311 Enumeration allConnections = freeConnections.elements(); <br>
              312 while (allConnections.hasMoreElements()) { <br>
              313 Connection con = (Connection) allConnections.nextElement(); <br>
              314 try { <br>
              315 con.close(); <br>
              316 log("关闭连接池" + name+"中的一个连接"); <br>
              317 } <br>
              318 catch (SQLException e) { <br>
              319 log(e, "无法关闭连接池" + name+"中的连接"); <br>
              320 } <br>
              321 } <br>
              322 freeConnections.removeAllElements(); <br>
              323 } <br>
              324 <br>
              325 /** <br>
              326 * 创建新的连接 <br>
              327 */ <br>
              328 private Connection newConnection() { <br>
              329 Connection con = null; <br>
              330 try { <br>
              331 if (user == null) { <br>
              332 con = DriverManager.getConnection(URL); <br>
              333 } <br>
              334 else { <br>
              335 con = DriverManager.getConnection(URL, user, password); <br>
              336 } <br>
              337 log("连接池" + name+"创建一个新的连接"); <br>
              338 } <br>
              339 catch (SQLException e) { <br>
              340 log(e, "无法创建下列URL的连接: " + URL); <br>
              341 return null; <br>
              342 } <br>
              343 return con; <br>
              344 } <br>
              345 } <br>
              346 }
              </font><p><font size="2">三、类DBConnectionPool说明\ </font></p>
              <p><font size="2">该
类在209至345行实现，它表示指向某个数据库的连接池。数据库由JDBC URL标识。一个JDBC
URL由三部分组成：协议标识（总是jdbc），驱动程序标识（如
odbc、idb、oracle等），数据库标识（其格式依赖于驱动程序）。例如，jdbc:odbc:demo，即是一个指向demo数据库的JDBC
URL，而且访问该数据库要使用JDBC-ODBC驱动程序。每个连接池都有一个供客户程序使用的名字以及可选的用户帐号、密码、最大连接数限制。如果
Web应用程序所支持的某些数据库操作可以被所有用户执行，而其它一些操作应由特别许可的用户执行，则可以为两类操作分别定义连接池，两个连接池使用相同
的JDBC URL，但使用不同的帐号和密码。 <br>
                类DBConnectionPool的建构函数需要上述所有数据作为其参数。如222至238行所示，这些数据被保存为它的实例变量： <br>
如252至283行、285至305行所示，
客户程序可以使用DBConnectionPool类提供的两个方法获取可用连接。两者的共同之处在于：如连接池中存在可用连接，则直接返回，否则创建新
的连接并返回。如果没有可用连接且已有连接总数等于最大限制数，第一个方法将直接返回null，而第二个方法将等待直到有可用连接为止。 <br>
所有的可用连接对象均登记在名为freeConnections的向量（Vector）中。如果向量中有多于一个的连接，getConnection()
总是选取第一个。同时，由于新的可用连接总是从尾部加入向量，从而使得数据库连接由于长时间闲置而被关闭的风险减低到最小程度。 <br>
第一个getConnection()在返回可用连接给客户程序之前，调用了isClosed()方法验证连接仍旧有效。如果该连接被关闭或触发异常，
getConnection()递归地调用自己以尝试获取另外的可用连接。如果在向量freeConnections中不存在任何可用连接，
getConnection()方法检查是否已经指定最大连接数限制。如已经指定，则检查当前连接数是否已经到达极限。此处maxConn为0表示没有限
制。如果没有指定最大连接数限制或当前连接数小于该值，该方法尝试创建新的连接。如创建成功，则增加已使用连接的计数并返回，否则返回空值。 <br>
                如325至345行所示，创建新连接由newConnection()方法实现。创建过程与是否已经指定数据库帐号、密码有关。 <br>
JDBC的DriverManager类提供多个getConnection()方法，这些方法要用到JDBC
URL与其它一些参数，如用户帐号和密码等。DriverManager将使用指定的JDBC URL确定适合于目标数据库的驱动程序及建立连接。 <br>
                在285至305行实现的第二个getConnection()方法需要一个以毫秒为单位的时间参数，该参数表示客户程序能够等待的最长时间。建立连接的具体操作仍旧由第一个getConnection()方法实现。 <br>
该方法执行时先将startTime初始化为当前时间。在while循环中尝试获得一个连接。如果失败，则以给定的时间值为参数调用wait()。
wait()的返回可能是由于其它线程调用notify()或notifyAll()，也可能是由于预定时间已到。为找出wait()返回的真正原因，程
序用当前时间减开始时间（startTime），如差值大于预定时间则返回空值，否则再次调用getConnection()。 <br>
把空闲的连接登记到连接池由240至250行的freeConnection()方法实现，它的参数为返回给连接池的连接对象。该对象被加入到
freeConnections向量的末尾，然后减少已使用连接计数。调用notifyAll()是为了通知其它正在等待可用连接的线程。 <br>
许多Servlet引擎为实现安全关闭提供多种方法。数据库连接池需要知道该事件以保证所有连接能够正常关闭。DBConnectionManager类
负协调整个关闭过程，但关闭连接池中所有连接的任务则由DBConnectionPool类负责。在307至323行实现的release()方法供
DBConnectionManager调用。该方法遍历freeConnections向量并关闭所有连接，然后从向量中删除这些连接。 </font></p>
              <p><font size="2">四、类DBConnectionManager 说明\ </font></p>
              <p><font size="2">该类只能创建一个实例，其它对象能够调用其静态方法（也称为类方法）获得该唯一实例的引用。如031至036行所示，DBConnectionManager类的建构函数是私有的，这是为了避免其它对象创建该类的实例。 <br>
DBConnectionManager类的客户程序可以调用getInstance()方法获得对该类唯一实例的引用。如018至029行所示，类的唯
一实例在getInstance()方法第一次被调用期间创建，此后其引用就一直保存在静态变量instance中。每次调用getInstance()
都增加一个DBConnectionManager的客户程序计数。即，该计数代表引用DBConnectionManager唯一实例的客户程序总数，
它将被用于控制连接池的关闭操作。 <br>
该类实例的初始化工作由146至168行之间的私有方法init()完成。其中
getResourceAsStream()方法用于定位并打开外部文件。外部文件的定位方法依赖于类装载器的实现。标准的本地类装载器查找操作总是开始
于类文件所在路径，也能够搜索CLASSPATH中声明的路径。db.properties是一个属性文件，它包含定义连接池的键-值对。可供定义的公用
属性如下： </font></p>
              <p><font size="2">drivers 以空格分隔的JDBC驱动程序类列表\ <br>
                logfile 日志文件的绝对路径 </font></p>
              <p><font size="2">其它的属性和特定连接池相关，其属性名字前应加上连接池名字： </font></p>
              <p><font size="2">< poolname>.url 数据库的 JDBC URL <br>
              < poolname>.maxconn 允许建立的最大连接数，0表示没有限制 <br>
              < poolname>.user 用于该连接池的数据库帐号 <br>
              < poolname>.password 相应的密码\ </font></p>
              <p><font size="2">其中url属性是必需的，而其它属性则是可选的。数据库帐号和密码必须合法。用于Windows平台的db.properties文件示例如下： </font></p>
              <p><font size="2">drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver <br>
                logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt </font></p>
              <p><font size="2">idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp <br>
                idb.maxconn=2 </font></p>
              <p><font size="2">access.url=jdbc:odbc:demo <br>
                access.user=demo <br>
                access.password=demopw </font></p>
              <p><font size="2">注意在Windows路径中的反斜杠必须输入2个，这是由于属性文件中的反斜杠同时也是一个转义字符。 <br>
init()方法在创建属性对象并读取db.properties文件之后，就开始检查logfile属性。如果属性文件中没有指定日志文件，则默认为当
前目录下的DBConnectionManager.log文件。如日志文件无法使用，则向System.err输出日志记录。 <br>
装载和注册所有在drivers属性中指定的JDBC驱动程序由170至192行之间的loadDrivers()方法实现。该方法先用
StringTokenizer将drivers属性值分割为对应于驱动程序名称的字符串，然后依次装载这些类并创建其实例，最后在
DriverManager中注册该实例并把它加入到一个私有的向量drivers。向量drivers将用于关闭服务时从DriverManager取
消所有JDBC 驱动程序的注册。 <br>
init()方法的最后一个任务是调用私有方法createPools()创建连接池对象。如109至142行所示，createPools()方法先创
建所有属性名字的枚举对象（即Enumeration对象，该对象可以想象为一个元素系列，逐次调用其nextElement()方法将顺序返回各元
素），然后在其中搜索名字以“.url”结尾的属性。对于每一个符合条件的属性，先提取其连接池名字部分，进而读取所有属于该连接池的属性，最后创建连接
池对象并把它保存在实例变量pools中。散列表（Hashtable类
）pools实现连接池名字到连接池对象之间的映射，此处以连接池名字为键，连接池对象为值。 <br>
为便于客户程序从指定连接池获得可用连接或将连接返回给连接池，类DBConnectionManager提供了方法getConnection()和
freeConnection()。所有这些方法都要求在参数中指定连接池名字，具体的连接获取或返回操作则调用对应的连接池对象完成。它们的实现分别在
051至064行、066至080行、038至049行。 <br>
如082至107行所示，为实现连接池的安全关闭，DBConnectionManager提供了方法release()。在上面我们已经提到，所有
DBConnectionManager的客户程序都应该调用静态方法getInstance()以获得该管理器的引用，此调用将增加客户程序计数。客户
程序在关闭时调用release()可以递减该计数。当最后一个客户程序调用release()，递减后的引用计数为0，就可以调用各个连接池的
release()方法关闭所有连接了。管理类release()方法最后的任务是撤销所有JDBC驱动程序的注册。 </font></p>
              <p><font size="2">五、Servlet使用连接池示例 </font></p>
              <p><font size="2">Servlet API所定义的Servlet生命周期类如： </font></p>
              <p><font size="2">1) 创建并初始化Servlet（init()方法）。 <br>
                2) 响应客户程序的服务请求（service()方法）。 <br>
                3) Servlet终止运行，释放所有资源（destroy()方法）。 </font></p>
              <p><font size="2">本例演示连接池应用，上述关键步骤中的相关操作为： </font></p>
              <p><font size="2">1) 在init()，用实例变量connMgr 保存调用DBConnectionManager.getInstance()所返回的引用。 <br>
                2) 在service()，调用getConnection()，执行数据库操作，用freeConnection()将连接返回给连接池。 <br>
                3) 在destroy()，调用release()关闭所有连接，释放所有资源。 </font></p>
              <p><font size="2">示例程序清单如下： </font></p>
              <p><font size="2">import
java.io.*;import java.sql.*;import javax.servlet.*;import
javax.servlet.http.*;public class TestServlet extends HttpServlet {
private DBConnectionManager connMgr; public void init(ServletConfig
conf) throws ServletException { super.init(conf); connMgr =
DBConnectionManager.getInstance(); } public void
service(HttpServletRequest req, HttpServletResponse res) throws
IOException { res.setContentType("text/html"); PrintWriter out =
res.getWriter(); Connection con = connMgr.getConnection("idb"); if (con
== null) { out.println("不能获取数据库连接."); return; } ResultSet rs = null;
ResultSetMetaData md = null; Statement stmt = null; try { stmt =
con.createStatement(); rs = stmt.executeQuery("SELECT * FROM
EMPLOYEE"); md = rs.getMetaData(); out.println("< H1>职工数据<
/H1>"); while (rs.next()) { out.println("< BR>"); for (int i =
1; i < md.getColumnCount(); i++) { out.print(rs.getString(i) + ",
"); } } stmt.close(); rs.close(); } catch (SQLException e) {
e.printStackTrace(out); } connMgr.freeConnection("idb", con); } public
void destroy() { connMgr.release(); super.destroy(); }} </font></p><img src ="http://www.blogjava.net/hellotony/aggbug/29266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hellotony/" target="_blank">Tony</a> 2006-01-26 17:52 <a href="http://www.blogjava.net/hellotony/articles/29266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>.Net 与 Oracle 的数据库连接池</title><link>http://www.blogjava.net/hellotony/articles/29265.html</link><dc:creator>Tony</dc:creator><author>Tony</author><pubDate>Thu, 26 Jan 2006 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/hellotony/articles/29265.html</guid><wfw:comment>http://www.blogjava.net/hellotony/comments/29265.html</wfw:comment><comments>http://www.blogjava.net/hellotony/articles/29265.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hellotony/comments/commentRss/29265.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hellotony/services/trackbacks/29265.html</trackback:ping><description><![CDATA[<p class="style36"><font size="2">概述 ： </font></p>
      <p class="style36"><font size="2"> 　　数据库连接池允许应用程序重用已存在于池中的数据库连接，以避免反复的建立新的数据库连接。这种技术能有效提高应用程序的伸缩性，因为有限的数据库连接能够给大量的客户提供服务。这种技术同时也提高的系统性能，避免了大量建立新连接的开销。 
        </font></p>
      <p class="style36"><font size="2"> 　　开发一个具有伸缩性的、高性能应用程序应该最大限度的减少建立连接所花费的时间，保持数据库连接最大限度的有效，以存取数据。当一个数据库连接关闭时，它只是由连接池收回以待重用，并未真正释放。但是，如果连接池被释放，数据库连接将会被释放掉。 
        </font></p>
      <p class="style36"><font size="2">　　开发人员应当注意不要依赖垃圾回收机制去释放数据库连接，因为当参数超出作用域时，数据库连接并没有得必要的关闭，这种数据库资源泄漏将导致建立新连接时抛出连接错误。 
        </font></p>
      <h2 class="style36"><font size="2">建立数据库连接池 </font></h2>
      <p class="style36"><font size="2">　　当打开一个数据库连接时，一个数据库连接池也就创建了。数据库连接池的创建与数据库连接字符串精确的相关（包括空格、大小写）。所有的连接池是根据连接字符串来区分的。在创建一个新的数据库连接时，如果连接字符串不完全相同，将创建不同的连接池。 
        </font></p>
      <p class="style36"><font size="2">　　一旦数据库连接池被创建，它将一直存在直到该进程结束。维护一个非活动状态的连接池几乎不需要什么系统开销。 
        </font></p>
      <h2 class="style36"><font size="2">连接池中的数据库连接 </font></h2>
      <p class="style36"><font size="2">　　连接池根据唯一的连接字符串被创建。在连接池被创建的同时，连接池将创建最小的数据库连接，当连接不够用时，连接池将逐个添加数据库连接直到达到最大连接数，此后的连接请求将被加入请求队列里。当调用数据库连接对象的 
        Close 方法或Ｄ ispose 方法时，数据库连接将被数据库连接池回收。 </font></p>
      <p class="style36"><font size="2">　　当数据库连接使用完成后，要调用 Close 方法或 Dispose 方法将它返回连接池。没有显式释放的数据库连接可能会没有返回连接池。 
        </font></p>
      <p class="style36"><font size="2">　　注意不要在类的 Finalize 方法中调用任何管理类如 Connection 
        ， DataReader 等的 Finalize 方法，必须将数据库连接的释放权交给连接池。 </font></p>
      <h2 class="style36"><font size="2">释放数据库连接 </font></h2>
      <p class="style36"><font size="2">　　当数据库连接超时或服务已经完成时，连接池将会将其资源释放，这只能通过试图与数据库通讯来判断。如果发现数据库连接不可用，它将被标记为不可用资源。数据库连接池将定时扫描数据库连接，释放所有不可用资源。 
        </font></p>
      <p class="style36"><font size="2">　　如果发现现有的数据库连接不可用，那么可能是该连接被数据库连接池标记为不可用资源了，这时将抛出一个异常。尽管如此，你还是必须释放连接，将它返回连接池。 
        </font></p>
      <h2 class="style36"><font size="2">支持 Transaction </font></h2>
      <p class="style36"><font size="2">　　数据库连接池内的数据库连接是按照 Transaction Context 
        划分的，每当连接池接到连接请求时，他将返回与请求者 Transaction Context 相匹配的数据库连接。因此，每个连接池都由数个 Transaction 
        Context 相关的数据库连接和一个 Transaction Context 无关的数据库连接组成。当数据库连接被返回连接池时，它将被放回对应的 
        Transaction Context 组中。 </font></p>
      <h2 class="style36"><font size="2">用连接字符串关键字控制数据库连接池 </font></h2>
      <p class="style36"><font size="2">　　OracleConnection 对象的属性 ConnectionString 
        有一些能支持连接池控制的 key-value 字符串。下表是这些 key-value 字符串的详细说明。 </font></p>
      <p class="style36"><font size="2">  </font></p>
      <table border="1" cellpadding="0" cellspacing="0">
        <tbody><tr> 
          <td class="style36" valign="bottom" width="30%"><p><font size="2">名称 
              </font></p></td>
          <td class="style36" valign="bottom" width="13%"><p><font size="2">默认值 
              </font></p></td>
          <td class="style36" valign="bottom" width="57%"><p><font size="2">说明 
              </font></p></td>
        </tr>
        <tr> 
          <td class="style36" valign="top" width="30%"><p><font size="2">Connection 
              Lifetime </font></p></td>
          <td class="style36" valign="top" width="13%"><p><font size="2">0 </font></p></td>
          <td class="style36" valign="top" width="57%"><p><font size="2">当数据库连接被返回到连接池中时，它的创建时间将与当前时间比较，如果超过了 
              Connection Lifetime 规定的时间，它将被释放掉。 </font></p>
            <p><font size="2">为 0 时将被视为最大连接时间。 </font></p></td>
        </tr>
        <tr> 
          <td class="style36" valign="top" width="30%"><p><font size="2">Enlist 
              </font></p></td>
          <td class="style36" valign="top" width="13%"><p><font size="2">'true' 
              </font></p></td>
          <td class="style36" valign="top" width="57%"><p><font size="2">当此值为 
              true 时，池中现存的所有数据库连接将被加入到它的创建线程的 Transaction Context 中。如果不存在这个 Transaction 
              Context 则无任何变化。 </font></p></td>
        </tr>
        <tr> 
          <td class="style36" valign="top" width="30%"><p><font size="2">Max Pool 
              Size </font></p></td>
          <td class="style36" valign="top" width="13%"><p><font size="2">100 </font></p></td>
          <td class="style36" valign="top" width="57%"><p><font size="2">连接池能建立的最大数据库连接数。 
              </font></p></td>
        </tr>
        <tr> 
          <td class="style36" valign="top" width="30%"><p><font size="2">Min Pool 
              Size </font></p></td>
          <td class="style36" valign="top" width="13%"><p><font size="2">0 </font></p></td>
          <td class="style36" valign="top" width="57%"><p><font size="2">连接池要保持的最小数据库连接数。 
              </font></p></td>
        </tr>
        <tr> 
          <td class="style36" valign="top" width="30%"><p><font size="2">Pooling 
              </font></p></td>
          <td class="style36" valign="top" width="13%"><p><font size="2">'true' 
              </font></p></td>
          <td class="style36" valign="top" width="57%"><p><font size="2">当设为 true 
              时，数据库连接将由相应的连接池管理。 </font></p></td>
        </tr>
      </tbody></table>
      <p class="style36"><font size="2">  </font></p><img src ="http://www.blogjava.net/hellotony/aggbug/29265.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hellotony/" target="_blank">Tony</a> 2006-01-26 17:48 <a href="http://www.blogjava.net/hellotony/articles/29265.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>