发表于: os/software | 作者: | 日期: 2008/11/03 01:11
标签: ,

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>netstat help

显示协议统计信息和当前 TCP/IP 网络连接。

NETSTAT [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval]

-a 显示所有连接和监听端口。
-b 显示包含于创建每个连接或监听端口的
可执行组件。在某些情况下已知可执行组件
拥有多个独立组件,并且在这些情况下
包含于创建连接或监听端口的组件序列
被显示。这种情况下,可执行组件名
在底部的 [] 中,顶部是其调用的组件,
等等,直到 TCP/IP 部分。注意此选项
可能需要很长时间,如果没有足够权限
可能失败。
-e 显示以太网统计信息。此选项可以与 -s
选项组合使用。
-n 以数字形式显示地址和端口号。
-o 显示与每个连接相关的所属进程 ID。
-p proto 显示 proto 指定的协议的连接;proto 可以是
下列协议之一: TCP、UDP、TCPv6 或 UDPv6。
如果与 -s 选项一起使用以显示按协议统计信息,proto 可以是下列协议
之一:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。
-r 显示路由表。
-s 显示按协议统计信息。默认地,显示 IP、
IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息;
-p 选项用于指定默认情况的子集。
-v 与 -b 选项一起使用时将显示包含于
为所有可执行组件创建连接或监听端口的
组件。
interval 重新显示选定统计信息,每次显示之间
暂停时间间隔(以秒计)。按 CTRL+C 停止重新
显示统计信息。如果省略,netstat 显示当前
配置信息(只显示一次)

C:\Documents and Settings\Administrator>^A

评论关闭
发表于: os/software | 作者: | 日期: 2008/11/03 01:11

Manipulates network routing tables.

ROUTE [-f] [-p] [command [destination] [MASK netmask] [gateway] [METRIC metric] [IF interface]

-f
Clears the routing tables of all gateway entries. If this is used in conjunction with one of the commands, the tables are cleared prior to running the command.

-p
When used with the ADD command, makes a route persistent across boots of the system. By default, routes are not preserved when the system is restarted. Ignored for all other commands, which always affect the appropriate persistent routes. This option is not supported in Windows 95.

command
One of these:
PRINT Prints a route
ADD Adds a route
DELETE Deletes a route
CHANGE Modifies an existing route

destination Specifies the host.

MASK
Specifies that the next parameter is the ‘netmask’ value.

netmask
Specifies a subnet mask value for this route entry.
If not specified, it defaults to 255.255.255.255.

gateway
Specifies gateway.

interface
the interface number for the specified route.

METRIC
specifies the metric, ie. cost for the destination.

All symbolic names used for destination are looked up in the network database file NETWORKS. The symbolic names for gateway are looked up in the host name database file HOSTS.

If the command is PRINT or DELETE. Destination or gateway can be a wildcard, (wildcard is specified as a star ‘*’), or the gateway argument may be omitted.

If Dest contains a * or ?, it is treated as a shell pattern, and only
matching destination routes are printed. The ‘*’ matches any string,
and ‘?’ matches any one char. Examples: 157.*.1, 157.*, 127.*, *224*.
Diagnostic Notes:
Invalid MASK generates an error, that is when (DEST & MASK) != DEST.
Example> route ADD 157.0.0.0 MASK 155.0.0.0 157.55.80.1 IF 1
The route addition failed: The specified mask parameter is invalid.
(Destination & Mask) != Destination.

Examples:

> route PRINT
> route ADD 157.0.0.0 MASK 255.0.0.0 157.55.80.1 METRIC 3 IF 2
destination^ ^mask ^gateway metric^ ^
Interface^
If IF is not given, it tries to find the best interface for a given
gateway.
> route PRINT
> route PRINT 157* …. Only prints those matching 157*
> route CHANGE 157.0.0.0 MASK 255.0.0.0 157.55.80.5 METRIC 2 IF 2

CHANGE is used to modify gateway and/or metric only.
> route PRINT
> route DELETE 157.0.0.0
> route PRINT

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 10:11
标签:

J2EE应用中与Oracle数据库的连接
在J2EE应用程序开发中,应用程序与数据库连接的建立是我们经常遇到的问题之一。在这里我主要谈谈在本地应用程序中通过OCI方式、thin方式和JdbcOdbc桥方式连接Oracle数据库,在iPlanet Application Server 6.5和Sun ONE Application Server 7中对Oracle数据库连接池的配置以及应用中如何从连接池中获得连接。
一、本地通过JDBC获得Oracle数据库连接
通过JDBC获得Oracle数据库连接,有三种方式:OCI方式、thin方式和JdbcOdbc桥方式。OCI方式依赖于本地的动态链接库,如果在本地安装了Oracle数据库客户端可以采用该方式;而thin方式为纯java的数据库连接方式;JdbcOdbc桥方式依赖于本地ODBC数据库源的配置,这种方式一般不太被采用。
1、OCI方式
先在本地安装Oracle客户端,安装完之后,在安装的路径中可以找到…/jdbc/lib/classes12.zip文件,我们在环境变量classpath中设置classes12.zip所在的路径。 然后通过以下的数据库连接类,在本地通过OCI方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*; import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过OCI方式获得Oracle数据库连接
*/
public class DbConnection
{
  final static String sDBDriver = “oracle.jdbc.driver.OracleDriver”;
  final static String sConnStr = “jdbc:oracle:oci8:sr/sr@ora199”;
  /**
  *
  */
  public DbConnection() { }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByOci()
  {
   java.sql.Connection conn=null;
    try {
        Class.forName(sDBDriver);
        conn = DriverManager.getConnection(sConnStr);
      }
    catch (Exception e)
    {
        System.out.println(“ERROR:”+e.getMessage());
    }
    return conn;
  }
}
  在连接字符串 “jdbc:oracle:oci8:sr/sr@ora199” 中,”sr/sr”为Oracle用户的用户名和口令,”ora199″为数据库服务名。
2、thin方式
先到Oracle技术网(http://otn.oracle.com/global/cn/software/tech/java/sqlj_jdbc/index.html)下载Oracle JDBC Drivers,同样地将下载后的zip文件的路径设置在环境变量classpath。然后通过以下的数据库连接类,在本地通过thin方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过thin方式获得Oracle数据库连接
*/
public class DbConnection
{
    private String sConnStr = “”;
    /**
    * 缺省构造器
    */
    public DbConnection()
    {
         sConnStr = “jdbc:oracle:thin:@10.1.4.199:1521:ora199”;
    }
    /**
    * @param ip,serviceName
    */
    public DbConnection(String ip,String serviceName)
    {
       sConnStr = “jdbc:oracle:thin:@”+ip+”:1521:”+serviceName;
    }
    /**
    * 通过thin方式获得Oracle数据库的连接.
    */
    public java.sql.Connection connectDbByThin()
    {
         java.sql.Connection conn=null;
         try
         {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(sConnStr,”sr”,”sr”);
         }
         catch (Exception e)
         {
            System.out.println(“ERROR:”+e.getMessage());
         }
         return conn;
    }
    /**
    *通过thin方式获得Oracle数据库的连接.
    * @param userId,password
    */
    public java.sql.Connection connectByJdbc(String userId,String password)
    {
        java.sql.Connection conn=null;
        try
        {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(sConnStr,userId,password);
        }
        catch (Exception e)
        {
            System.out.println(“ERROR:”+e.getMessage());
        }
        return conn;
    }
}
这种方式运用起来比较灵活,简单,具有较强的移植性和适用性。只要注意连接字符串”jdbc:oracle:thin:@10.1.4.199:1521:ora199″中具体参数的设置即可。
3、JdbcOdbc桥方式
  先通过管理工具中的数据源来添加本地对Oracle数据库的连接,然后通过以下的数据库连接类,在本地通过JdbcOdbc桥方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过JdbcOdbc桥方式获得Oracle数据库连接
*/
public class DbConnection {
  /**
  *
  */
  public DbConnection()
  {
  }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByJdbcOdbcBridge()
  {
     java.sql.Connection conn=null;
     try
     {
         Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);          con=DriverManager.getConnection(“jdbc:odbc:ora199″,”sr”,”sr”);
     }
     catch (Exception e)
     {
         System.out.println(“ERROR:”+e.getMessage());
     }
     return conn;
  }
}
  在getConnection方法中第一个参数”jdbc:odbc:ora199″ 中的”ora199″为本地ODBC数据源的数据源名称,第二个参数和第三个参数分别为Oracle的用户名和口令。
二、通过连接池获得Oracle数据库连接
  这部分主要讲述在iPlanet Application Server 6.5和Sun ONE Application Server 7中Oracle数据库连接池的配置,以及在应用中如何通过连接池获得数据库的连接。
1、iPlanet Application Server 6.5连接池的配置
  先打开iPlanet Application Server 6.5的管理控制台,选中”database”面板,再选择”External JDBC Drivers”选项后,点击”Add…”按钮,在弹出的对话框中,添加一个名为”ora-type4″的JDBC Driver。

  Driver Classpath:该参数填写classes12.zip文件的物理路径。
  然后在”External JDBC DataSources”中选择”Add…”,在弹出的对话框中添加一个JNDI名称为”credit2″的数据源。

  DriverType:选择刚添加好的”ora-type4″;
  Datasource:ora199,为Oracle数据库服务名;
  Connection Pool Parameters:图中显示的是缺省设置,可以根据自己环境情况来更改这些设置。
  保存完设置后,在”DataSource Selection Box”中,选择刚添加的”credit2″数据源,再选择”Vendor Specific Properties”按钮。在对话中添加一个URL属性。

  至此,iPlanet Application Server 6.5中的数据库连接池配置完毕,重起服务使之生效。
2、Sun ONE Application Server 7连接池的配置
  在配置之前将classes12.zip文件置于…/server1/lib目录下。通过浏览器的4848端口打开Sun ONE Application Server 7的管理界面,选择”server1″->”JDBC”-> “Connection Pools”下的”New…”

  添加一个名称为”MyConnectionPool”的Oracle数据库连接池。”Next”下一步。

  在”General”中填写”Datasource Classname”。

  在”Properties”中将不需要的属性删除,同时添加”URL”属性。
  ”dataSourceName”中填写Oracle数据库服务名。
  以下连接池的缺省设置,可以根据自己环境的情况作相应的调整。

选择”Finish”完成连接池的设置。
下一步为”MyConnectionPool”连接池创建一个JNDI,以便应用程序能够通过该名称获得连接池中的连接。 “server1″->”JDBC”-> “JDBC Resources”下的”New…”

  至此,Sun ONE Application Server7中的数据库连接池配置完毕,重起服务使之生效。
3、通过连接池获得连接
  以上在iPlanet Application Server 6.5和Sun ONE Application Server7中配置的连接池都可以通过以下的数据库连接类,从连接池中获得Oracle数据库连接。
/**
* 从连接池中获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过连接池方式获得Oracle数据库连接
*/
public class DbConnection {
  /**
  *
  */
  public DbConnection()
  {
  }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByConnectionPool()
  {
     java.sql.Connection conn=null;
     try
     {
        Context ctx = new InitialContext();
        DataSource ds = (DataSource)ctx.lookup(“jdbc/credit2”);
        conn=ds.getConnection();
     }
     catch (Exception e)
     {
        System.out.println(“ERROR:”+e.getMessage());
     }
     return conn;
  }
}
4、使用连接池的优点
使用连接池的优点主要体现在两个方面:
1. 对数据库的连接统一进行配置、管理、监控,以及对数据库连接池的参数进行优化调整,同时对应用中没有关闭或其他原因造成没有关闭的数据库连接由连接池统一进行管理。
2. 便于应用的移植和后端数据库的切换,因为在应用中通过统一的JNDI获得数据库的连接,而具体连接的是哪一台机器上的数据库与应用无关。
作者:洪建
URL:http://www.dbonline.cn/source/oracle/20040404/OTHER_J2EE%20CONNECT%20ORACLE.htm

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 10:11
标签:

JDBC编程学习笔记
1:JDBC概述
JDBC 是一种用于执行 SQL 语句的 Java API,JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序。简单地说,JDBC 可做三件事:(1)与数据库建立连接,(2)发送 SQL 语句,(3)处理结果。

2: JDBC驱动程序的类型

(1)JDBC-ODBC桥加ODBC驱动程序
JavaSoft桥产品利用ODBC驱动程序提供JDBC访问。注意,必须将ODBC二进制代码(许多情况下还包括数据库客户机代码)加载到使用该驱动程序的每个客户机上。因此,这种类型的驱动程序最适合于企业网(这种网络上客户机的安装不是主要问题),或者是用Java编写的三层结构的应用程序服务器代码。

(2)本地API
这种类型的驱动程序把客户机API上的JDBC调用转换为Oracle、Sybase、Informix、DB2或其它DBMS的调用。注意,象桥驱动程序一样,这种类型的驱动程序要求将某些二进制代码加载到每台客户机上。

(3)JDBC网络纯Java驱动程序
这种驱动程序将JDBC转换为与DBMS无关的网络协议,之后这种协议又被某个服务器转换为一种DBMS协议。这种网络服务器中间件能够将它的纯Java客户机连接到多种不同的数据库上。所用的具体协议取决于提供者。通常,这是最为灵活的JDBC驱动程序。有可能所有这种解决方案的提供者都提供适合于Intranet用的产品。为了使这些产品也支持Internet访问,它们必须处理Web所提出的安全性、通过防火墙的访问等方面的额外要求。几家提供者正将JDBC驱动程序加到他们现有的数据库中间件产品中。

(4)本地协议纯Java驱动程序
这种类型的驱动程序将JDBC调用直接转换为DBMS所使用的网络协议。这将允许从客户机机器上直接调用DBMS服务器,是Intranet访问的一个很实用的解决方法。由于许多这样的协议都是专用的,因此数据库提供者自己将是主要来源,有几家提供者已在着手做这件事了。

据专家预计第(3)、(4)类驱动程序将成为从JDBC访问数据库的首方法。第(1)、(2)类驱动程序在直接的纯Java驱动程序还没有上市前会作为过渡方案来使用。对第(1)、(2)类驱动程序可能会有一些变种,这些变种要求有连接器,但通常这些是更加不可取的解决方案。第(3)、(4)类驱动程序提供了Java的所有优点,包括自动安装(例如,通过使用JDBC驱动程序的applet来下载该驱动程序)。

3:JDBC数据库访问步骤
简单示例程序如下:
package employeetree.db.main;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DbDriver {

//连接字符串
private static final String strDriver = “oracle.jdbc.driver.OracleDriver”;
private static final String strPassword = “duckbill61_a”;
private static final String strUrl = “jdbc:oracle:thin:@172.20.92.2:1521:ora9i”;
private static final String strUsername = “duckbill61_a”;

public static void main(String[] args){
Connection conn = null;
try{
Class.forName(strDriver);
conn = DriverManager.getConnection(strUrl,strUsername,strPassword);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“select * from employee”);
while(rs.next()){
System.out.println(rs.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}

(1)注册驱动程序
(2)建立连接
(3)发送SQL语句
(5)处理返回集
(6)善后处理

4:JDBC常用对象
DriverManager
DriverManager 类是 JDBC 的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。
对于简单的应用程序,一般程序员需要在此类中直接使用的唯一方法是DriverManager.getConnection。正如名称所示,该方法将建立与数据库的连接。JDBC允许用户调用DriverManager的方法getDriver、getDrivers和registerDriver及Driver的方法connect。但多数情况下,让DriverManager类管理建立连接的细节为上策。

Connection
Connection 对象代表与数据库的连接。连接过程包括所执行的 SQL 语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。2.1.1 打开连接与数据库建立连接的标准方法是调用DriverManager.getConnection方法。该方法接受含有某个 URL 的字符串。DriverManager 类(即所谓的 JDBC管理层)将尝试找到可与那个 URL 所代表的数据库进行连接的驱动程序。DriverManager 类存有已注册的 Driver 类的清单。当调用方法 getConnection 时,它将检查清单中的每个驱动程序,直到找到可与URL 中指定的数据库进行连接的驱动程序为止。Driver 的方法connect 使用这个 URL来建立实际的连接。

Statement
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement对象,它们都作为在给定连接上执行SQL语句的包装器:Statement、PreparedStatement(它从Statement继承而来)和CallableStatement(它从PreparedStatement继承而来)。它们都专用于发送特定类型的SQL语句:Statement对象用于执行不带参数的简单SQL语句;PreparedStatement对象用于执行带或不带IN参数的预编译SQL语句;CallableStatement对象用于执行对数据库已存储过程的调用。

Statement接口提供了执行语句和获取结果的基本方法;PreparedStatement接口添加了处理IN参数的方法;而CallableStatement添加了处理OUT参数的方法。

创建Statement对象
建立了到特定数据库的连接之后,就可用该连接发送SQL语句。Statement对象用Connection的方法createStatement创建,如下列代码段中所示:

Connection con = DriverManager.getConnection(url,”sunny”,””);
Statement stmt = con.createStatement();

为了执行Statement对象,被发送到数据库的SQL语句将被作为参数提供给Statement的方法:
ResultSet rs = stmt.executeQuery(”SELECT a,b,c FROM Table2″);

使用Statement对象执行语句
Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute。使用哪一个方法由SQL语句所产生的内容决定。
方法executeQuery用于产生单个结果集的语句,例如SELECT语句。方法executeUpdate用于执行INSERT、UPDATE或DELETE语句以及SQL DDL(数据定义语言)语句,例如CREATE TABLE和DROP TABLE。INSERT、UPDATE或DELETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE或DROP TABLE等不操作行的语句,executeUpdate的返回值总为零。
执行语句的所有方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。应注意,继承了Statement接口中所有方法的PreparedStatement接口都有自己的executeQuery、executeUpdate和execute方法。Statement对象本身不包含SQL语句,因而必须给Statement.execute方法提供SQL语句作为参数。PreparedStatement对象并不需要SQL语句作为参数提供给这些方法,因为它们已经包含预编译SQL语句。

CallableStatement对象继承这些方法的PreparedStatement形式。对于这些方法的PreparedStatement或CallableStatement版本,使用查询参数将抛出SQLException。

语句完成
当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的executeQuery方法,在检索完ResultSet对象的所有行时该语句完成。对于方法executeUpdate,当它执行时语句即完成。但在少数调用方法execute的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。
有些DBMS将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用commit方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。

关闭Statement对象
Statement对象将由Java垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要Statement对象时显式地关闭它们。这将立即释放DBMS资源,有助于避免潜在的内存问题。

使用方法execute
execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程或动态执行未知SQL字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。例如,用户可能执行一个已存储过程,并且该已存储过程可执行更新,然后执行选择,再进行更新,再进行选择,等等。通常使用已存储过程的人应知道它所返回的内容。

因为方法execute处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法execute执行该过程后,必须调用方法getResultSet获得第一个结果集,然后调用适当的getXXX方法获取其中的值。要获得第二个结果集,需要先调用getMoreResults方法,然后再调用getResultSet方法。如果已知某个过程返回两个更新计数,则首先调用方法getUpdateCount,然后调用getMoreResults,并再次调用getUpdateCount。

对于不知道返回内容,则情况更为复杂。如果结果是ResultSet对象,则方法execute返回true;如果结果是Javaint,则返回false。如果返回int,则意味着结果是更新计数或执行的语句是DL命令。在调用方法execute之后要做的第一件事情是调用getResultSet或getUpdateCount。调用方法getResultSet可以获得两个或多个ResultSet对象中第一个对象;或调用方法getUpdateCount可以获得两个或多个更新计数中第一个更新计数的内容。

当SQL语句的结果不是结果集时,则方法getResultSet将返回null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断null真正含义的唯一方法是调用方法getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为-1则表示结果是结果集或没有结果。如果方法getResultSet已返回null(表示结果不是ResultSet对象),则返回值-1表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果):

  ((stmt.getResultSet()==null)&&(stmt.getUpdateCount()==-1))

  如果已经调用方法getResultSet并处理了它返回的ResultSet对象,则有必要调用方法getMoreResults以确定是否有其它结果集或更新计数。如果getMoreResults返回true,则需要再次调用getResultSet来检索下一个结果集。如上所述,如果getResultSet返回null,则需要调用getUpdateCount来检查null是表示结果为更新计数还是表示没有其它结果。

  当getMoreResults返回false时,它表示该SQL语句返回一个更新计数或没有其它结果。因此需要调用方法getUpdateCount来检查它是哪一种情况。在这种情况下,当下列条件为真时表示没有其它结果:

  ((stmt.getMoreResults()==false)&&(stmt.getUpdateCount()==-1))

  下面的代码演示了一种方法用来确认已访问调用方法execute所产生的全部结果集和更新计数:

stmt.execute(queryStringWithUnknownResults);
while(true){
introwCount=stmt.getUpdateCount();
if(rowCount>0){//它是更新计数
System.out.println(”Rows changed=”+count);
stmt.getMoreResults();
continue;
}
if(rowCount==0){//DDL命令或0个更新
System.out.println(”No rows changed or statement was DDL command”);
stmt.getMoreResults();
continue;
}
//执行到这里,证明有一个结果集
//或没有其它结果
ResultSet rs=stmt.getResultSet();
if(rs!=null){
…//使用元数据获得关于结果集列的信息
while(rs.next()){
…//处理结果
stmt.getMoreResults();
continue;
}
break;//没有其它结果

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 10:11
标签:

JDBC性能优化技巧
 如果可能,避免访问数据库
此条在ESM中的表现就是对职员信息的访问,能从Session中读取的总是尽可能从Session中读取,数据库的操作总是尽量避免。

 对数据库使用连接池并且重用连接,而不要重复打开和关闭连接。最佳的连接池大小是当连接池大到足够使服务请求不等待
“池”及类似的概念是所有高性能系统所必备的部件,比如硬盘及光盘驱动器的预读取策略

Prepared statement 池(自从 JDBC3.0 开始有)高速缓存已经预先优化并运行了的 SQL 查询,这样,他们被再次请求的时候,不必经历再次的优化预处理(避免最优化步骤,诸如检查语法,验证地址,优化访问路径和执行计划)。 Statement 池是一个很好的,重要的性能优化方法

JDBC3.0 中的 Statement 池和连接池能合作共享 statement 池,这样,能使用一个已高速缓存的 statement (该 statement 来自另外一个连接)的连接,在由任一连接执行的 一些SQL 首次被执行时,产生的 statement 准备开销仅一次

RowSet对象与 ResultSet 对象相似,但是能提供当断开连接的时候对数据库数据的访问。这允许数据以它最简单的形式被高效的高速缓存
这个特性不知有何用处?

 用同一个连接执行多个 statements
在ESM中,一次(http)请求连接只打来一个Connection,所有的Statement都位于这一个Connection中,当断开(http)连接的时候,才会提交所有事务。

 关闭 autocommit ,但不要让事务打开太久
ESM中即采取了此策略。

避免将事务分布开(事务跨越多个连接)

最小化数据库的行和列数据获取。使用 setMaxRows, setMaxFieldSize,和 SetFetchSize

使用最高效的数据类型:字符串比整数型快,整数型比浮点类型和时间戳类型都要高效(是否不太理解^&^,这是针对DB2数据库处理来说的,处理character类型最快,而处理integer类型通常需要一些转换或者字节排序)

使用 updateXXX()方法更新: updateXXX() 在可更新的结果集上调用。结果集已经定位到了一行 , 因此当使用一个 UPDATE statement 时,可以消除通常的查找要更新的数据行的开销

Cache任何请求的元数据( metadata )并尽可能少的使用元数据 方法,其慢的程度一用便知

避免在元数据 查询中使用 null 参数

使用虚拟查询获得一行的元数据,不要使用getcolumns()(假如应用允许用户使用列数据,应用是使用getColumns来返回列的信息给用户还是准备一个虚拟查询而后调用getMetadata呢?

使用存储过程,避免多余的网络传输

在存储过程中使用参量,不要将数据挨个地放在statement中,最小化解析开销。此条针对DB2来说,其它数据库未必适用。SQL总是以字符串形式发送给DB2数据库,例如:
CallableStatement cstmt = conn.prepareCall (“call getCustName (12345)”);
ResultSet rs = cstmt.executeQuery ();
DB2服务器必须解析该SQL,验证参量类型,并将参量转化为正确的数据类型。

对需要重复执行的statement使用预处理statement(PreparedStatement)

选择使用最佳游标:对连续读取使用游标;对双向滚动使用游标。对仅返回一行的查询避免使用游标。

在JVM中Cache频繁请求的数据,避免不必要的数据库请求

采用预读取机制, 批量取行,而不要一次一行 。调整批大小和预取行的数量。避免使用预取 BLOB 数据。

除非绝对需要,否则避免移动数据

在数据穿过网络之前要使流化数据( Streamline data )

避免每次处理一行,尽可能一起处理多行。

在表中统计个数(例如:使用 select count(*) from myTable,yourTable where …)属于资源密集型的。试试首先选入临时表,仅返回该计数(count),然后发送精确的二次查询获得临时表中的行的子集。

恰当的使用 SQL 能减少资源请求。使用返回所需数据的最小值的查询:避免 select * 查询。一个返回小的数据子集的复杂查询,比一个简单的,返回超过所需的大量数据的简单查询更高效。

使你的查询尽可能精巧,例如:尽可能精确地最小化要传输的数据,使其是所需的子集

努力批量更新:将 statement 收集到一起,然后在一个事务里面一起执行。如果可能,使用有条件的逻辑和临时变量来达到 statement 批处理

永远不要让 DBMS 事务跨越用户输入

考虑使用乐观锁。乐观锁使用时间戳验证数据是否还没有被其他用户改变,否则事务失败

使用 恰当的更新,例如:更新行/表中已经存在的数据,而不要添加或者删除行/表。在适当的位置更新数据要比移动数据快得多,如果更新需要的空间比表设计能提供的更多,这可能是需要的。如果你设计的行需要空间初始化,更新将会更快。交易是你的表可能需要更多的磁盘空间,但可能速度更快。由于磁盘空间是便宜的,使用一点点能提高性能,这应该说是非常有价值的投资

分开存储正在操作的数据和历史数据(更一般的情况是将频繁使用的数据和不常使用的数据分开存储)

尽可能小的保留你的操作数据集,避免必须读那些不相关的数据

DBMS可以很好的并行运转,尽量将应用设计成当和 DBMS交互时应用能做其他事情。

使用流水线操作和并行操作。 将应用设计成支持大量并行进程, 使应用运行更快。如果要处理多步,努力设计好应用,以使后来的步骤能够在任何优先的进程已经完成的数据部分上开始工作,而不是必须等到优先进程完成

事物的保护级别越高,性能损失就越大。事物级别按增长的顺序为: TRANSACTION_NONE, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, TRANSACTION_REPEATABLE_READ, TRANSACTION_SERIALIZABLE。使用Connection.setTransactionIsolation() 设置你想要的事物级别

默认的自动提交模式由于使每一个数据库命令都成为一个单独的事务,这会严重影响性能,关闭自动提交(Connection.setAutoCommit(false) ),明确声明事务

通过整合多个事务为一个的批量操作,并在一个statement中使用Statement.addBatch() 和Statement.executeBatch()

Savepoints (from JDBC3.0)需要昂贵的资源。一旦不再需要,就立刻使用Connection.releaseSavepoint()释放掉Savepoints

ConnectionPoolDataSource (from JDBC3.0)和PooledConnection接口为连接池提供了built-in支持

使用setLogWriter() (from Driver, DataSource, or ConnectionPooledDataSource; from JDBC3.0) 帮助跟踪JDBC流

使用Connection.setReadOnly(true)优化只读数据库(操作)交互

使用Connection.nativeSQL()察看SQL查询如何在数据库种执行,帮助确保SQL已被优化

切记:一旦可能,立刻关闭Statement和ResultSet

使用DatabaseMetaData获得数据库功能性信息

一直捕捉和处理数据库警告和异常

使用最恰当的数据类型明确数据的类型,例如:以date类型存储日期,儿不要用varchar

使用可滚动ResultSet (JDBC 2.0)

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 08:11

JSP的四种范围,分别为page、request、session、application。 More …

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 08:11
标签:

综述:Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。 More …

评论关闭
发表于: DB/ES | 作者: | 日期: 2008/11/03 08:11
标签:

在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM, COUNT, MAX, AVG等。这些函数和其它函数的根本区别就是它们一般作用在多条记录上。 SELECT SUM(population) FROM bbc

这里的SUM作用在所有返回记录的population字段上,结果就是该查询只返回一个结果,即所有国家的总人口数。

通过使用GROUP BY 子句,可以让SUM 和 COUNT 这些函数对属于一组的数据起作用。当你指定 GROUP BY region 时, 属于同一个region(地区)的一组数据将只能返回一行值,也就是说,表中所有除region(地区)外的字段,只能通过 SUM, COUNT等聚合函数运算后返回一个值。

HAVING子句可以让我们筛选成组后的各组数据,WHERE子句在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前.

而 HAVING子句在聚合后对组记录进行筛选。

让我们还是通过具体的实例来理解GROUP BY 和 HAVING 子句。

SQL实例:

一、显示每个地区的总人口数和总面积: SELECT region, SUM(population), SUM(area)

FROM bbc

GROUP BY region

先以region把返回记录分成多个组,这就是GROUP BY的字面含义。分完组后,然后用聚合函数对每组中的不同字段(一或多条记录)作运算。

二、 显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。 SELECT region, SUM(population), SUM(area)

FROM bbc

GROUP BY region

HAVING SUM(area)>1000000

在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。

相反,HAVING子句可以让我们筛选成组后的各组数据

group by
分组
通用数据库具有基于表的特定列对数据进行分析的能力。
可按照在 GROUP BY 子句中定义的组对行进行分组。以其最简单的形式,组由称为分组列的列组成。 SELECT 子句中的列名必须为分组列或列函数。列函数对于 GROUP BY 子句定义的每个组各返回一个结果。下列示例产生一个列出每个部门编号的最高薪水的结果:
SELECT DEPT, MAX(SALARY) AS MAXIMUM
FROM STAFF
GROUP BY DEPT
此语句产生下列结果:
DEPT MAXIMUM
—— ———
10 22959.20
15 20659.80
20 18357.50
38 18006.00
42 18352.80
51 21150.00
66 21000.00
84 19818.00
注意:计算的是每个部门(由 GROUP BY 子句定义的组)而不是整个公司的 MAX(SALARY)。
将 WHERE 子句与 GROUP BY 子句一起使用
分组查询可以在形成组和计算列函数之前具有消除非限定行的标准 WHERE 子句。必须在GROUP BY 子句之前指定 WHERE 子句。例如:
SELECT WORKDEPT, EDLEVEL, MAX(SALARY) AS MAXIMUM
FROM EMPLOYEE
WHERE HIREDATE > ‘1979-01-01’
GROUP BY WORKDEPT, EDLEVEL
ORDER BY WORKDEPT, EDLEVEL

结果为:
WORKDEPT EDLEVEL MAXIMUM
——– ——- ———–
D11 17 18270.00
D21 15 27380.00
D21 16 36170.00
D21 17 28760.00
E11 12 15340.00
E21 14 26150.00
注意:在 SELECT 语句中指定的每个列名也在 GROUP BY 子句中提到。未在这两个地方提到的列名将产生错误。GROUP BY 子句对 WORKDEPT 和 EDLEVEL 的每个唯一组合各返回一行。
在 GROUP BY 子句之后使用 HAVING 子句
可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。为此,在GROUP BY 子句后面包含一个 HAVING 子句。 HAVING 子句可包含一个或多个用 AND 和 OR 连接的谓词。每个谓词将组特性(如 AVG(SALARY))与下列之一进行比较:
该组的另一个特性
例如:
HAVING AVG(SALARY) > 2 * MIN(SALARY)
常数
例如:
HAVING AVG(SALARY) > 20000
例如,下列查询寻找雇员数超过 4 的部门的最高和最低薪水:
SELECT WORKDEPT, MAX(SALARY) AS MAXIMUM, MIN(SALARY) AS MINIMUM
FROM EMPLOYEE
GROUP BY WORKDEPT
HAVING COUNT(*) > 4
ORDER BY WORKDEPT
此语句产生下列结果:
WORKDEPT MAXIMUM MINIMUM
——– ———– ———–
D11 32250.00 18270.00
D21 36170.00 17250.00
E11 29750.00 15340.00
有可能(虽然很少见)查询有 HAVING 子句但没有 GROUP BY 子句。在此情况下,DB2 将整个表看作一个组。因为该表被看作是单个组,所以最多可以有一个结果行。如果 HAVING 条件对整个表为真,则返回选择的结果(该结果必须整个由列函数组成);否则不返回任何行。

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 08:11
标签:

创建一个日期对象

使用系统的当前日期和时间创建一个日期对象并返回一个长整数的简单例子。 这个时间通常被称为Java 虚拟机(JVM)主机环境的系统时间。

import java.util.Date;
public class DateExample1 {
public static void main(String[] args) {
// Get the system date/time
Date date = new Date();
System.out.println(date.getTime());
}
}

今天是星期一,2005年8月8日,上午8:43,上面的例子在系统输出设备上显示的结果是1123461832312。

日期数据的定制格式

使用类java.text.SimpleDateFormat和它的抽象基类 java.text.DateFormat 完成日期数据的格式定制,比方今天星期一-八月-08-2005。下面的例子展示了如何完成这个工作:

import java.text.SimpleDateFormat;
import java.util.Date;
public class DateExample2 {
public static void main(String[] args) {
SimpleDateFormat bartDateFormat = new SimpleDateFormat(“EEEE-MMMM-dd-yyyy”);
Date date = new Date();
System.out.println(bartDateFormat.format(date));
}
}

只要通过向SimpleDateFormat 的构造函数传递格式字符串”EEE-MMMM-dd-yyyy”,就能够指明自己想要的格式。运行结果就是:星期一-八月-08-2005 了。传递”EE-MM-dd-yy”会显示 星期一-08-08-05 。

将文本数据解析成日期对象

假设一个文本字符串包含了一个格式化了的日期对象,而需要解析这个字符串并从文本日期数据创建一个日期对象。下面的例子,将解析文本字符串”8-8-2005″并创建一个值为1123430400000 的日期对象。

例子程序:

import java.text.SimpleDateFormat; import java.util.Date;
public class DateExample3{ public static void main(String[] args) { // Create a date formatter that can parse dates of the form MM-dd-yyyy. SimpleDateFormat bartDateFormat = new SimpleDateFormat(“MM-dd-yyyy”); // Create a string containing a text date to be parsed. String dateStringToParse = “8-8-2005”; try { // Parse the text version of the date. //We have to perform the parse method in a //try-catch construct in case dateStringToParse //does not contain a date in the format we are expecting. Date date = bartDateFormat.parse(dateStringToParse); // Now send the parsed date as a long value // to the system output. System.out.println(date.getTime()); } catch (Exception ex){ System.out.println(ex.getMessage()); } } }

使用标准的日期格式化过程

可以生成和解析定制的日期格式后,现在来看一看如何使用内建的格式化过程。使用方法DateFormat.getDateTimeInstance()可以得到用几种不同的方法获得标准的日期格式化过程。在下面的例子中,我们获取了四个内建的日期格式化过程。它们包括一个短的,中等的,长的,和完整的日期格式。

import java.text.DateFormat; import java.util.Date;

public class DateExample4{ public static void main(String[] args) { Date date = new Date(); DateFormat shortDateFormat = DateFormat.getDateTimeInstance (DateFormat.SHORT,DateFormat.SHORT); DateFormat mediumDateFormat = DateFormat.getDateTimeInstance (DateFormat.MEDIUM,DateFormat.MEDIUM); DateFormat longDateFormat = DateFormat.getDateTimeInstance (DateFormat.LONG,DateFormat.LONG); DateFormat fullDateFormat = DateFormat.getDateTimeInstance DateFormat.FULL,DateFormat.FULL);

System.out.println(shortDateFormat.format(date)); System.out.println(mediumDateFormat.format(date)); System.out.println(longDateFormat.format(date)); System.out.println(fullDateFormat.format(date)); } }

注意我们在对 getDateTimeInstance的每次调用中都传递了两个值。 第一个参数是日期风格, 而第二个参数是时间风格。 它们都是基本数据类型int(整型)。考虑到可读性,这里使用了DateFormat 类提供的常量: SHORT, MEDIUM, LONG, 和 FULL。

运行例子程序, 它将向标准输出设备输出下面的内容:

05-8-8 上午9:17 2005-8-8 9:17:42 2005年8月8日 上午09时17分42秒2005年8月8日 09时17分42秒 GMT+08:00

(完成 程序测试结果基于JDK1.2.2)

阅读全文(76) | 回复(2) | 引用(0)
回复:java Date 显示格式
[ chenglong发表评论于2005-8-10 2:51:06 ]
第一个要求很简单的,就是先定制一个年月日字符型格式的日期,然后将它解析成一个日期对象;再设置一个只显示星期几的日期的格式,将上面的日期对象格式输出就行了。

第二个要求也不难,你是想对数据库中的数据操作,我这里就用数组给你模拟一下吧。我定义了两个int变量SHANGBAN,XIUXI,对应你的两个字段值1和0,然后我对8月的数据进行了操作(我是假设双休日休息,对应今年的这个月),根据输入的年月日字符,用substing提取了各个字段,然后进行相应查找就行了。你可以用各个字段到数据库中相应的那一天查询对应的值就ok了。

下面是我的程序:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.lang.String;
import java.lang.Integer;
public class DateExample{
public static void main(String[] args){
int SHANGBAN = 1; //上班
int XIUXI = 0; //休息
int[] AugDay = { //八月份数据
SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,XIUXI,XIUXI,
SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,XIUXI,XIUXI,
SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,XIUXI,XIUXI,
SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,SHANGBAN,XIUXI,XIUXI,
SHANGBAN,SHANGBAN,SHANGBAN
};
// Create a date formatter that can parse dates of the form yyyy-MM-dd.
SimpleDateFormat bartDateFormat1 = new SimpleDateFormat(“yyyy-MM-dd”);
// Create a string containing a text date to be parsed.
String dateStringToParse = “2005-8-10”; //可以改成接受输入
try {
Date date = bartDateFormat1.parse(dateStringToParse);
SimpleDateFormat bartDateFormat2 = new SimpleDateFormat(“EEEE”);
System.out.println(dateStringToParse + ” ” +bartDateFormat2.format(date));

int year = Integer.parseInt(dateStringToParse.substring(0,4));
int month = Integer.parseInt(dateStringToParse.substring(5,6));
int day = Integer.parseInt(dateStringToParse.substring(7,9));

if(month == 8){
//假如输入的是8月份的话(这里只是演示,指的是今年8月,你可以按你的需要修改)
if(AugDay[day-1] == SHANGBAN){
System.out.println(“今天上班”);
}
else{
System.out.println(“今天休息”);
}
}
}
catch (Exception ex){
System.out.println(ex.getMessage());
}
}
}

输入时间是2005-8-10,只用了八月的数组里的值来显示大体的意思,你完全可以修改满足你的需要。最后显示结果为:

2005-8-10 星期三
今天上班

好了,应该很清楚了吧,加油,也感谢你的支持!

I LOVE JAVA!

posted on 2005-09-15 11:38 sharky的点滴积累 阅读(699) 评论(0) 编辑 收藏

评论关闭
发表于: DB/ES | 作者: | 日期: 2008/11/03 08:11
标签:

表    tree
  字段   master
       sub
       sales
  insert into tree values
  (‘主1’,   ‘主2’,  15); 
  insert into tree values   
  (‘主1’,   ‘主3’,  20);     
  insert into tree values
  (‘主2’,   ‘主4’,  5);          
  insert into tree values
  (‘主2’,   ‘主5’,  10);
  insert into tree values
  (‘主3’,   ‘主5’,  30);
  insert into tree values
  (‘主3’,   ‘主6’,  40);
  
  SQL> select * from tree;
  MASTER   SUB       SALES
  ———- ———- ———-
  主1    主2        15
  主1    主3        20
  主2    主4         5
  主2    主5        10
  主3    主5        30
  主3    主6        40 
  
  如果用树型结构表示如下:
   ’主1’          
     -‘主2’       
       –‘主4’
       –‘主5’
   ’主1’          
     -‘主3’       
       –‘主5’
       –‘主6′
  
  SQL> select * from tree                
  start with sub=’主2’     –相当于普通sql的where条件
  connect by prior master=sub; –遍历的顺序是sub先于master遍历,也就是说从sub往上遍历一直到master(根节点)
   2 
  MASTER   SUB       SALES
  ———- ———- ———-
  主1    主2        15
  
  
  SQL> select * from tree                
  start with master=’主2′
  connect by prior master=sub; –sub往上遍历至根节点(参考一下树型图)              
   2  3 
  MASTER   SUB       SALES      
  ———- ———- ———-      
  主2    主4         5  –这条是自己本身,也就是第一遍遍历
  主1    主2        15  –这是第2次遍历,我们从树型图可以看到,’主2’往上遍历是’主1’     
  主2    主5        10      
  主1    主2        15      
                        
                         
                        
  好,我们关看上面可能还是不好理解,我们加入一个树结构专用函数sys_connect_by_path,便于理解
  
  SQL> select sys_connect_by_path(MASTER,’/’) from tree  –master表示我遍历的起点只找在master列中存在的,如下例只要’主2’为起点,并以/为分割符
  start with master=’主2′
  connect by prior master=sub;  –往根节点遍历
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,’/’)
  ——————————————————————————–
  /主2             –第1遍遍历
  /主2/主1          –第2遍遍历
  /主2             –第2条master=’主2’的记录的第1次遍历
  /主2/主1          –第2条master=’主2’的记录的第2次遍历
  
  SQL> select sys_connect_by_path(MASTER,’/’) from tree –起点为sub=’主5’时MASTER=主2,主3
  start with sub=’主5′
  connect by prior master=sub;
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,’/’)
  ——————————————————————————–
  /主2
  /主2/主1
  /主3
  /主3/主1
  
  SQL> select sys_connect_by_path(MASTER,’/’),sub,master from tree  
  start with sub is not null
  connect by prior master=sub; 
   2  3 
  SYS_CONNECT_BY_PATH(MASTER,’/’ SUB    MASTER
  —————————— ———- ———-
  /主1              主2    主1 –找主1到根的路径,这里根是主1他自己
  /主1              主3    主1 
  /主2              主4    主2 
  /主2/主1           主2    主1 –找主2到根的路径,这里根是主1
  /主2              主5    主2
  /主2/主1           主2    主1 
  /主3              主5    主3 
  /主3/主1           主3    主1
  /主3              主6    主3
  /主3/主1           主3    主1  
  select sys_connect_by_path(MASTER,’/’),sub,master from tree                
  start with sub is not null
  connect by prior sub = master;                       
  
  SYS_CONNECT_BY_PATH(MASTER,’/’ SUB    MASTER
  —————————— ———- ———-
  /主1              主2    主1
  /主1/主2           主4    主2
  /主1/主2           主5    主2
  /主1              主3    主1
  /主1/主3           主5    主3
  /主1/主3           主6    主3
  /主2              主4    主2
  /主2              主5    主2
  /主3              主5    主3
  /主3              主6    主3
________________________________________
Go to source web page: Oracle–树的使用(Connect By) – 开发者在线 – www.builder.com.cn

评论关闭