??xml version="1.0" encoding="utf-8" standalone="yes"?>波多野结衣av在线播放,国产999在线观看,啊v视频在线http://www.aygfsteel.com/rkind/category/4183.html<font size=5 align=right>知h者智 自知者明 Fighting!!</font>zh-cnFri, 02 Mar 2007 03:25:31 GMTFri, 02 Mar 2007 03:25:31 GMT60单的Jsp文本计数?/title><link>http://www.aygfsteel.com/rkind/archive/2006/01/19/28631.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Thu, 19 Jan 2006 03:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/rkind/archive/2006/01/19/28631.html</guid><wfw:comment>http://www.aygfsteel.com/rkind/comments/28631.html</wfw:comment><comments>http://www.aygfsteel.com/rkind/archive/2006/01/19/28631.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/rkind/comments/commentRss/28631.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/rkind/services/trackbacks/28631.html</trackback:ping><description><![CDATA[<P>把以下代码粘贴到首页中,可以从counter.txt中读取访问量?BR>一定要注意路径的问题,刚开始直接用counter.txtQ结果L找不到文Ӟ而且用绝对\径也不行Q?BR>但是?counter.txt没有问?BR><%!<BR>int number=0;<BR>    synchronized void countPeople(){<BR>        if(number==0){<BR>            try{<BR>                FileInputStream in=new FileInputStream("/counter.txt");<BR>                DataInputStream dataIn=new DataInputStream(in);<BR>                number=dataIn.readInt();<BR>                number++;<BR>                in.close();<BR>                dataIn.close();<BR>            }catch(FileNotFoundException e){<BR>    <BR>                number++;<BR>                try{<BR>                    FileOutputStream out=new FileOutputStream("/counter.txt");<BR>                    DataOutputStream dataOut=new DataOutputStream(out);<BR>                    dataOut.writeInt(number);<BR>                    out.close();<BR>                    dataOut.close();<BR>                }catch(IOException ffe){<BR>                    System.out.print(ffe);<BR>                }<BR>            }catch(IOException ee){<BR>   System.out.println(ee);<BR>            }<BR>            }else{<BR>            number++;<BR>            try{<BR>                FileOutputStream out=new FileOutputStream("/counter.txt");<BR>                DataOutputStream dataOut=new DataOutputStream(out);<BR>                dataOut.writeInt(number);<BR>                out.close();<BR>                dataOut.close();<BR>            }catch(FileNotFoundException e){<BR>    System.out.println(e);<BR>   }<BR>            catch(IOException e){<BR>    System.out.println(e);<BR>   }</P> <P>        }<BR>    }</P> <P>%><BR><% countPeople();%></P><img src ="http://www.aygfsteel.com/rkind/aggbug/28631.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/rkind/" target="_blank">rkind</a> 2006-01-19 11:26 <a href="http://www.aygfsteel.com/rkind/archive/2006/01/19/28631.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>抽象cM接口的区别[转]http://www.aygfsteel.com/rkind/archive/2005/12/06/22681.htmlrkindrkindTue, 06 Dec 2005 03:03:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/12/06/22681.htmlhttp://www.aygfsteel.com/rkind/comments/22681.htmlhttp://www.aygfsteel.com/rkind/archive/2005/12/06/22681.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/22681.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/22681.htmlabstract class和interface是Java语言中对于抽象类定义q行支持的两U机Ӟ正是׃q两U机制的存在Q才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的怼性,甚至可以怺替换Q因此很多开发者在q行抽象cd义时对于abstract class和interface的选择昑־比较随意?BR>其实Q两者之间还是有很大的区别的Q对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意囄理解是否正确、合理。本文将对它们之间的区别q行一番剖析,试图l开发者提供一个在二者之间进行选择的依据?BR>一、理解抽象类
abstract class和interface在Java语言中都是用来进行抽象类Q本文中的抽象类q从abstract class译而来Q它表示的是一个抽象体Q而abstract class为Java语言中用于定义抽象类的一U方法,误者注意区分)定义的,那么什么是抽象c,使用抽象c能为我们带来什么好处呢Q?BR>在面向对象的概念中,我们知道所有的对象都是通过cL描绘的,但是反过来却不是q样。ƈ不是所有的c都是用来描l对象的Q如果一个类中没有包含够的信息来描l一个具体的对象Q这Lcd是抽象类。抽象类往往用来表征我们在对问题领域q行分析、设计中得出的抽象概念,是对一pd看上M同,但是本质上相同的具体概念的抽象?BR>比如Q如果我们进行一个图形编辑Y件的开发,׃发现问题领域存在着圆、三角Şq样一些具体概念,它们是不同的Q但是它们又都属于Ş状这样一个概念,形状q个概念在问题领域是不存在的Q它是一个抽象概c正是因为抽象的概念在问题领域没有对应的具体概念Q所以用以表征抽象概늚抽象cL不能够实例化的?BR>在面向对象领域,抽象cM要用来进行类型隐藏。我们可以构造出一个固定的一l行为的抽象描述Q但是这l行为却能够有Q意个可能的具体实现方式。这个抽象描q就是抽象类Q而这一lQ意个可能的具体实现则表现为所有可能的zcR模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允怿改的Q同Ӟ通过从这个抽象体zQ也可扩展此模块的行为功能。熟悉OCP的读者一定知道,Z能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle)Q抽象类是其中的关键所在?BR>二、从语法定义层面看abstract class和interface
在语法层面,Java语言对于abstract class和interfacel出了不同的定义方式Q下面以定义一个名为Demo的抽象类Z来说明这U不同。用abstract class的方式定义Demo抽象cȝ方式如下Q?/FONT>

abstract class Demo ?
 abstract void method1(); 
 abstract void method2(); 
 ?
?/CCID_CODE>


使用interface的方式定义Demo抽象cȝ方式如下Q?

interface Demo { 
 void method1(); 
 void method2(); 
 ?
}


在abstract class方式中,Demo可以有自q数据成员Q也可以有非abstarct的成员方法,而在interface方式的实CQDemo只能够有静态的不能被修改的数据成员Q也是必须是static final的,不过在interface中一般不定义数据成员Q,所有的成员Ҏ都是abstract的。从某种意义上说Qinterface是一U特DŞ式的abstract class?
从编E的角度来看Qabstract class和interface都可以用来实?design by contract"的思想。但是在具体的用上面还是有一些区别的?
首先Qabstract class在Java语言中表C的是一U承关p,一个类只能使用一ơ承关pR但是,一个类却可以实现多个interface。也许,q是Java语言的设计者在考虑Java对于多重l承的支持方面的一U折中考虑吧?
其次Q在abstract class的定义中Q我们可以赋予方法的默认行ؓ。但是在interface的定义中Q方法却不能拥有默认行ؓQؓ了绕q这个限Ӟ必须使用委托Q但是这?增加一些复杂性,有时会造成很大的麻烦?
在抽象类中不能定义默认行存在另一个比较严重的问题Q那是可能会造成l护上的ȝ。因为如果后来想修改cȝ界面Q一般通过abstract class或者interface来表C)以适应新的情况Q比如,d新的Ҏ或者给已用的方法中d新的参数Q时Q就会非常的ȝQ可能要p很多的时_对于zcd多的情况Q尤为如此)。但是如果界面是通过abstract class来实现的Q那么可能就只需要修改定义在abstract class中的默认行ؓ可以了?
同样Q如果不能在抽象cM定义默认行ؓQ就会导致同LҎ实现出现在该抽象cȝ每一个派生类中,q反?one ruleQone place"原则Q造成代码重复Q同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心?BR>三、从设计理念层面看abstract class和interface
上面主要从语法定义和~程的角度论qCabstract class和interface的区别,q些层面的区别是比较低层ơ的、非本质的。本文将从另一个层面:abstract class和interface所反映出的设计理念Q来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概늚本质所在?
前面已经提到q,abstarct class在Java语言中体C一U承关p,要想使得l承关系合理Q父cdzcM间必d?is a"关系Q即父类和派生类在概忉|质上应该是相同的。对于interface 来说则不Ӟq不要求interface的实现者和interface定义在概忉|质上是一致的Q仅仅是实现了interface定义的契U而已。ؓ了便于理解Q下面将通过一个简单的实例q行说明?
考虑q样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Doorh执行两个动作open和closeQ此时我们可以通过abstract class或者interface来定义一个表C抽象概念的类型,定义方式分别如下所C:

使用abstract class方式定义DoorQ?

abstract class Door { 
 abstract void open(); 
 abstract void close()Q?
} 

使用interface方式定义DoorQ?

interface Door { 
 void open(); 
 void close(); 
}


其他具体的Doorcd可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看h好像使用abstract class和interface没有大的区别?BR>如果现在要求Doorq要h报警的功能。我们该如何设计针对该例子的cȝ构呢Q在本例中,主要是ؓ了展Cabstract class和interface反映在设计理念上的区别,其他斚w无关的问题都做了化或者忽略)下面罗列出可能的解x案,q从设计理念层面对这些不同的Ҏq行分析?BR>解决Ҏ一Q?BR>单的在Door的定义中增加一个alarmҎQ如下:

abstract class Door { 
 abstract void open(); 
 abstract void close()Q?
 abstract void alarm(); 
} 

  
或?

interface Door { 
 void open(); 
 void close(); 
 void alarm(); 
}


那么h报警功能的AlarmDoor的定义方式如下:

class AlarmDoor extends Door { 
 void open() { ?} 
 void close() { ?} 
 void alarm() { ?} 
} 

  
或?

class AlarmDoor implements Door ?
 void open() { ?} 
 void close() { ?} 
 void alarm() { ?} 
?/CCID_CODE>


q种Ҏq反了面向对象设计中的一个核心原则ISPQInterface Segregation PricipleQ,在Door的定义中把Door概念本n固有的行为方法和另外一个概?报警?的行为方法؜在了一赗这样引L一个问题是那些仅仅依赖于Doorq个概念的模块会因ؓ"报警?q个概念的改变(比如Q修改alarmҎ的参敎ͼ而改变,反之依然?
解决Ҏ二:
既然open、close和alarm属于两个不同的概念,ҎISP原则应该把它们分别定义在代表q两个概늚抽象cM。定义方式有Q这两个概念都用abstract class方式定义Q两个概念都使用interface方式定义Q一个概念用abstract class方式定义Q另一个概念用interface方式定义?
昄Q由于Java语言不支持多重承,所以两个概念都使用abstract class方式定义是不可行的。后面两U方式都是可行的Q但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意囄反映是否正确、合理。我们一一来分析、说明?
如果两个概念都用interface方式来定义,那么反映出两个问题Q?
1、我们可能没有理解清楚问题领域,AlarmDoor在概忉|质上到底是Doorq是报警器?
2、如果我们对于问题领域的理解没有问题Q比如:我们通过对于问题领域的分析发现AlarmDoor在概忉|质上和Door是一致的Q那么我们在实现时就没有能够正确的揭C我们的设计意图Q因为在q两个概늚定义上(均用interface方式定义Q反映不Zq含义?
如果我们对于问题领域的理解是QAlarmDoor在概忉|质上是DoorQ同时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢Q前面已l说q,abstract class在Java语言中表CZU承关p,而承关pd本质上是"is a"关系。所以对于Doorq个概念Q我们应该用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行ؓQ所以报警概念可以通过interface方式定义。如下所C:

abstract class Door { 
 abstract void open(); 
 abstract void close()Q?
} 
interface Alarm { 
 void alarm(); 
} 
class AlarmDoor extends Door implements Alarm { 
 void open() { ?} 
 void close() { ?} 
    void alarm() { ?} 
}


q种实现方式基本上能够明的反映出我们对于问题领域的理解Q正的揭示我们的设计意图。其实abstract class表示的是"is a"关系Qinterface表示的是"like a"关系Q大家在选择时可以作Z个依据,当然q是建立在对问题领域的理解上的,比如Q如果我们认为AlarmDoor在概忉|质上是报警器Q同时又hDoor的功能,那么上述的定义方式就要反q来了?
abstract class和interface是Java语言中的两种定义抽象cȝ方式Q它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概忉|质的理解、对于设计意囄反映是否正确、合理,因ؓ它们表现了概念间的不同的关系Q虽焉能够实现需求的功能Q。这其实也是语言的一U的惯用法,希望读者朋友能够细l体?/FONT>



rkind 2005-12-06 11:03 发表评论
]]>
rmi步步来[转]http://www.aygfsteel.com/rkind/archive/2005/11/15/19937.htmlrkindrkindTue, 15 Nov 2005 10:46:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/11/15/19937.htmlhttp://www.aygfsteel.com/rkind/comments/19937.htmlhttp://www.aygfsteel.com/rkind/archive/2005/11/15/19937.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/19937.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/19937.html   RMIQ远E方法调用(Remote Method InvocationQ是Enterprise JavaBeans的支柱,是徏立分布式Java应用E序的方侉K径。RMI是非常容易用的Q但是它非常的强大?BR>
       RMI的基是接口,RMI构架Z一个重要的原理Q定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的q程计算服务和用它的客L?BR>
一个正常工作的RMIpȝ׃面几个部分组成:

?nbsp;    q程服务的接口定?BR>
?nbsp;    q程服务接口的具体实?BR>
?nbsp;    桩(StubQ和框架QSkeletonQ文?BR>
?nbsp;    一个运行远E服务的服务?BR>
?nbsp;    一个RMI命名服务Q它允许客户端去发现q个q程服务

?nbsp;    cL件的提供者(一个HTTP或者FTP服务器)

?nbsp;    一个需要这个远E服务的客户端程?BR>
下面我们一步一步徏立一个简单的RMIpȝ。首先在你的机器里徏立一个新的文件夹Q以便放|我们创建的文gQؓ了简单v见,我们只用一个文件夹存放客户端和服务端代码,q且在同一个目录下q行服务端和客户端?BR>
如果所有的RMI文g都已l设计好了,那么你需要下面的几个步骤ȝ成你的系l:

1?nbsp; ~写q且~译接口的Java代码

2?nbsp; ~写q且~译接口实现的Java代码

3?nbsp; 从接口实现类中生成桩QStubQ和框架QSkeletonQ类文g

4?nbsp; ~写q程服务的主q行E序

5?nbsp; ~写RMI的客LE序

6?nbsp; 安装q且q行RMIpȝ


1?nbsp; 接口

W一步就是徏立和~译服务接口的Java代码。这个接口定义了所有的提供q程服务的功能,下面是源E序Q?BR>
//Calculator.java
//define the interface
import java.rmi.Remote;

public interface Calculator extends Remote
{
    public long add(long a, long b)
        throws java.rmi.RemoteException;

    public long sub(long a, long b)
        throws java.rmi.RemoteException;

    public long mul(long a, long b)
        throws java.rmi.RemoteException;

    public long div(long a, long b)
        throws java.rmi.RemoteException;
}
注意Q这个接口承自RemoteQ每一个定义的Ҏ都必LZ个RemoteException异常对象?BR>
建立q个文gQ把它存攑֜刚才的目录下Qƈ且编译?BR>
>javac Calculator.java

2?nbsp; 接口的具体实?BR>
下一步,我们p写远E服务的具体实现Q这是一个CalculatorImplcLӞ

//CalculatorImpl.java
//Implementation
import java.rmi.server.UnicastRemoteObject

public class CalculatorImpl extends UnicastRemoteObject implements Calculator
{

    // q个实现必须有一个显式的构造函敎ͼq且要抛Z个RemoteException异常
    public CalculatorImpl()
        throws java.rmi.RemoteException {
        super();
    }

    public long add(long a, long b)
        throws java.rmi.RemoteException {
        return a + b;
    }

    public long sub(long a, long b)
        throws java.rmi.RemoteException {
        return a - b;
    }

    public long mul(long a, long b)
        throws java.rmi.RemoteException {
        return a * b;
    }

    public long div(long a, long b)
        throws java.rmi.RemoteException {
        return a / b;
    }
}
       同样的,把这个文件保存在你的目录里然后编译他?BR>
       q个实现cM用了UnicastRemoteObject去联接RMIpȝ。在我们的例子中Q我们是直接的从UnicastRemoteObjectq个cMl承的,事实上ƈ不一定要q样做,如果一个类不是从UnicastRmeoteObject上承,那必M用它的exportObject()Ҏ去联接到RMI?BR>
       如果一个类l承自UnicastRemoteObjectQ那么它必须提供一个构造函数ƈ且声明抛Z个RemoteException对象。当q个构造函数调用了super()Q它久激zUnicastRemoteObject中的代码完成RMI的连接和q程对象的初始化?BR>


3?nbsp; 桩(StubsQ和框架QSkeletonsQ?BR>
下一步就是要使用RMI~译器rmic来生成桩和框架文Ӟq个~译q行在远E服务实现类文g上?BR>
>rmic CalculatorImpl

在你的目录下q行上面的命令,成功执行完上面的命o你可以发C个Calculator_stub.class文gQ如果你是用的Java2SDKQ那么你q可以发现Calculator_Skel.class文g?BR>


4?nbsp; L服务?BR>
q程RMI服务必须是在一个服务器中运行的。CalculatorServercL一个非常简单的服务器?BR>
//CalculatorServer.java
import java.rmi.Naming;

public class CalculatorServer {

   public CalculatorServer() {
     try {
       Calculator c = new CalculatorImpl();
       Naming.rebind("rmi://localhost:1099/CalculatorService", c);
     } catch (Exception e) {
       System.out.println("Trouble: " + e);
     }
   }

   public static void main(String args[]) {
     new CalculatorServer();
   }
}
       建立q个服务器程序,然后保存C的目录下Qƈ且编译它?BR>
5?nbsp; 客户?BR>
客户端源代码如下Q?BR>
//CalculatorClient.java



import java.rmi.Naming;
import java.rmi.RemoteException;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;

public class CalculatorClient {

    public static void main(String[] args) {
        try {
            Calculator c = (Calculator)
                           Naming.lookup(
                 "rmi://localhost
                        /CalculatorService");
            System.out.println( c.sub(4, 3) );
            System.out.println( c.add(4, 5) );
            System.out.println( c.mul(3, 6) );
            System.out.println( c.div(9, 3) );
        }
        catch (MalformedURLException murle) {
            System.out.println();
            System.out.println(
              "MalformedURLException");
            System.out.println(murle);
        }
        catch (RemoteException re) {
            System.out.println();
            System.out.println(
                        "RemoteException");
            System.out.println(re);
        }
        catch (NotBoundException nbe) {
            System.out.println();
            System.out.println(
                       "NotBoundException");
            System.out.println(nbe);
        }
        catch (
            java.lang.ArithmeticException
                                      ae) {
            System.out.println();
            System.out.println(
             "java.lang.ArithmeticException");
            System.out.println(ae);
        }
    }
}
       保存q个客户端程序到你的目录下(注意q个目录是一开始徏立那个,所有的我们的文仉在那个目录下Q,q且~译他?BR>


6?nbsp; q行RMIpȝ

现在我们建立了所有运行这个简单RMIpȝ所需的文Ӟ现在我们l于可以q行q个RMIpȝ啦!来n受吧?BR>
我们是在命o控制Cq行q个pȝ的,你必d启三个控制台H口Q一个运行服务器Q一个运行客LQ还有一个运行RMIRegistry?BR>
首先q行注册E序RMIRegistryQ你必须在包含你刚写的类的那么目录下q行q个注册E序?BR>
>rmiregistry

好,q个命o成功的话Q注册程序已l开始运行了Q不要管他,现在切换到另外一个控制台Q在W二个控制台里,我们q行服务器CalculatorServiceQ因为RMI的安全机制将在服务端发生作用,所以你必须增加一条安全策略。以下是对应安全{略的例?
grant {
permission java.security.AllPermission "", "";
};
注意:q是一条最单的安全{略,它允怓Q何h做Q何事,对于你的更加关键性的应用,你必L定更加详l安全策略?BR>现在Zq行服务端,你需要除客户c?CalculatorClient.class)之外的所有的cL件。确认安全策略在policy.txt文g之后,使用如下命o来运行服务器?BR>> java -Djava.security.policy=policy.txt CalculatorServer

q个服务器就开始工作了Q把接口的实现加载到内存{待客户端的联接。好现在切换到第三个控制収ͼ启动我们的客L?BR>Z在其他的机器q行客户端程序你需要一个远E接?Calculator.class) 和一个stub(CalculatorImpl_Stub.class)?使用如下命oq行客户?BR>prompt> java -Djava.security.policy=policy.txt CalculatorClient

如果所有的q些都成功运行,你应该看C面的输出Q?BR>
1
9
18
3
如果你看C上面的输出,恭喜你,你成功了Q你已经成功的创Z一个RMIpȝQƈ且他正工作了。即使你q行在同一个计机上,RMIq是使用了你的网l堆栈和TCP/IP去进行通讯Qƈ且是q行在三个不同的Java虚拟Z。这已经是一个完整的RMIpȝ?



rkind 2005-11-15 18:46 发表评论
]]>
sql常用语句http://www.aygfsteel.com/rkind/archive/2005/11/11/19269.htmlrkindrkindFri, 11 Nov 2005 03:25:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/11/11/19269.htmlhttp://www.aygfsteel.com/rkind/comments/19269.htmlhttp://www.aygfsteel.com/rkind/archive/2005/11/11/19269.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/19269.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/19269.htmlSELECT COUNT(*) AS Expr1 FROM History

DELETE FROM History WHERE (Id > 0)

truncate table youtable;

Z么要用TRUNCATE TABLE 语句代替DELETE语句Q当你用TRUNCATE TABLE语句Ӟ记录的删除是不作记录的。也是_q意味着TRUNCATE TABLE 要比DELETE快得多?



rkind 2005-11-11 11:25 发表评论
]]>
Jbuilder2006中?.5以下JDK的解x?/title><link>http://www.aygfsteel.com/rkind/archive/2005/10/27/17028.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Thu, 27 Oct 2005 05:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/rkind/archive/2005/10/27/17028.html</guid><wfw:comment>http://www.aygfsteel.com/rkind/comments/17028.html</wfw:comment><comments>http://www.aygfsteel.com/rkind/archive/2005/10/27/17028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/rkind/comments/commentRss/17028.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/rkind/services/trackbacks/17028.html</trackback:ping><description><![CDATA[Jbuilder2006自带?.5的JDK,但如果你q想l箋用JDK1.42Q如果只是在Jbuilder2006的tool->configure->JDKs中添加一个JDK1.42或更低版本,那么即你只写一个最单的HelloWorldE序QJbuilder2006都会l你报出镉K一串错误,~写的代码在Jbuilder2005中也无法q行。我在刚使用Jbuilder2006Ӟ被这个问题困惑了好久Q在|上查了好久也没有找到解决的Ҏ?BR>今天׃两个时Q终于在Jbuilder2006的帮助中查到了问题的原因。Jbuilder2006在运行编译工E时Q会针对特定版本的VMq行~译Q默认的是Java 2 SDK, v 5.0 And LateQ因此,如果工程用的?.5以下的JDKQ碰到都是java.lang.UnsupportedClassVersionErrorq个错误?BR><BR>解决的办法其实很单,只要更改q个选项p了。具体步骤如下:<BR>----------------------------------------------------------<BR>1、右键点dE文Ӟ选择属?properties),<BR>2、在属性窗口中选择 Build-->Java,在右边的选项中有四个下拉框,可以看到编译选项了,<BR>3、其中Compiler和Debug Option可以不用,只在Languege features和Target VM中选择相应的JDK版本可以了Q然后确定,一切OK?BR>附g中是配置的图片?BR>-----------------------------------------------------------<BR>如果在Target VM中选择了All Java SDKsQ那么你的class文g在用JDK1.1的VM上都可以q行QJbuilder2006帮助中是q么说的Q估计没几个人的机子上还在用JDK1.1?:-Q?BR><BR><img src ="http://www.aygfsteel.com/rkind/aggbug/17028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/rkind/" target="_blank">rkind</a> 2005-10-27 13:06 <a href="http://www.aygfsteel.com/rkind/archive/2005/10/27/17028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mysql中有的表不能被访?http://www.aygfsteel.com/rkind/archive/2005/10/27/17026.htmlrkindrkindThu, 27 Oct 2005 05:05:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17026.htmlhttp://www.aygfsteel.com/rkind/comments/17026.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17026.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17026.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17026.html今天在Mysql中徏立了一个名叫Option的表Q结果无论如何都不能讉KQ后来换了个名字OK了,应而想C是Mysql的保留字Q搜了一下,发现以下字段都是它的保留?/P>

action  add  aggregate  all 
alter  after  and  as 
asc  avg  avg_row_length  auto_increment 
between  bigint  bit  binary 
blob  bool  both  by 
cascade  case  char  character 
change  check  checksum  column 
columns  comment  constraint  create 
cross  current_date  current_time  current_timestamp 
data  database  databases  date 
datetime  day  day_hour  day_minute 
day_second  dayofmonth  dayofweek  dayofyear 
dec  decimal  default  delayed 
delay_key_write  delete  desc  describe 
distinct  distinctrow  double  drop 
end  else  escape  escaped 
enclosed  enum  explain  exists 
fields  file  first  float 
float4  float8  flush  foreign 
from  for  full  function 
global  grant  grants  group 
having  heap  high_priority  hour 
hour_minute  hour_second  hosts  identified 
ignore  in  index  infile 
inner  insert  insert_id  int 
integer  interval  int1  int2 
int3  int4  int8  into 
if  is  isam  join 
key  keys  kill  last_insert_id 
leading  left  length  like 
lines  limit  load  local 
lock  logs  long  longblob 
longtext  low_priority  max  max_rows 
match  mediumblob  mediumtext  mediumint 
middleint  min_rows  minute  minute_second 
modify  month  monthname  myisam 
natural  numeric  no  not 
null  on  optimize  option 
optionally  or  order  outer 
outfile  pack_keys  partial  password 
precision  primary  procedure  process 
processlist  privileges  read  real 
references  reload  regexp  rename 
replace  restrict  returns  revoke 
rlike  row  rows  second 
select  set  show  shutdown 
smallint  soname  sql_big_tables  sql_big_selects 
sql_low_priority_updates  sql_log_off  sql_log_update  sql_select_limit 
sql_small_result  sql_big_result  sql_warnings  straight_join 
starting  status  string  table 
tables  temporary  terminated  text 
then  time  timestamp  tinyblob 
tinytext  tinyint  trailing  to 
type  use  using  unique 
unlock  unsigned  update  usage 
values  varchar  variables  varying 
varbinary  with  write  when 
where  year  year_month  zerofill 




rkind 2005-10-27 13:05 发表评论
]]>
一D|q按星期划分q上传到数据库的代码 http://www.aygfsteel.com/rkind/archive/2005/10/27/17027.htmlrkindrkindThu, 27 Oct 2005 05:05:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17027.htmlhttp://www.aygfsteel.com/rkind/comments/17027.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17027.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17027.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17027.html打算要做一个工作ȝq_Q考虑到要实现周工作ȝ的功能就得先把一q先按某周某周区分开来,查了查Api

采用了calendarc,q把最后分的结果传到数据库Q?/P>

year        week          content

2005        1                 1月3日~Q月Q日

...              ...                .................... 

源码如下(其中DBcL我用来实现数据库q接用的)

import java.util.*;
import java.util.Date;
import java.sql.*;
import rkind.db;
public class shijian {
 public static void main(String args[]){
  int day,mon,year,week,dayofweek;  
  db base=new db();
  String content="";
  Calendar nova = Calendar.getInstance();
  
  Date d1=new Date(); 
  nova.setTime(d1);
  nova.set(2005,Calendar.JANUARY,1);
  //nova.add(Calendar.DATE,6);
  //day=nova.get(Calendar.WEEK_OF_YEAR );
  dayofweek=nova.get(Calendar.DAY_OF_WEEK  );
  while(dayofweek!=2){
  nova.add(Calendar.DATE,1);
  dayofweek=nova.get(Calendar.DAY_OF_WEEK  );
  }
  year=nova.get(Calendar.YEAR);
  //String sql=new String("insert into shijian(year,week,content) values('"+year+"','"+week+"','"+content+"')");
  //System.out.println("day+++:"+day);
  while(year==2005){ 
   week=nova.get(Calendar.WEEK_OF_YEAR );
   mon=nova.get(Calendar.MONTH)+1;
   day=nova.get(Calendar.DATE);
   
   content=mon+"?+day+"?+"~~ ";  
   
   System.out.print("W?+week+"?+":  "+mon+"?+day+"?);
   nova.add(Calendar.DATE,6);
   week=nova.get(Calendar.WEEK_OF_YEAR );
   mon=nova.get(Calendar.MONTH)+1;
   day=nova.get(Calendar.DATE);
   
   content+=mon+"?+day+"?;
   try{
    String sql=new String("insert into shijian(year,week,content) values('"+year+"','"+week+"','"+content+"')");
    base.executeUpdate(sql); 
   }catch(Exception e){System.out.println(e);}
   
   System.out.println("~~~~"+mon+"?+day+"?);
   
   
   
   nova.add(Calendar.DATE,1);
   week=nova.get(Calendar.WEEK_OF_YEAR );
   mon=nova.get(Calendar.MONTH)+1;
   day=nova.get(Calendar.DATE);
   year=nova.get(Calendar.YEAR);
   
   
  }
 
 } 
 
}

虽然功能上实CQ但是还有大量的重复代码Q和费语句,q就是没有好好重视J2se的结果,没办法,

边学J2EE边看Se吧,Q)



rkind 2005-10-27 13:05 发表评论
]]>
在Tomcat中配|数据源 http://www.aygfsteel.com/rkind/archive/2005/10/27/17022.htmlrkindrkindThu, 27 Oct 2005 05:03:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17022.htmlhttp://www.aygfsteel.com/rkind/comments/17022.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17022.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17022.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17022.htmlDatasource对象是由Tomcat提供的,因而需要用JNDI来获得Datasouce

在Javax.naming 中提供了Context接口Q?/P>

数据源的配置涉及到Server.xml和web.xmlQ需要在server.xml中加入如下内容:说明一下:我的数据库是MYsql

<Context path="/text" docBase="d:/upload" debug="0">
     <Resource name="jdbc/testDb" auth="Container"
                    type="javax.sql.DataSource"/>
          <ResourceParams name="jdbc/testDB">\\数据源的名称
            <parameter><name>username</name><value>root</value></parameter>数据库的名称
            <parameter><name>password</name><value>password</value></parameter>数据库密?BR>            <parameter><name>driverClassName</name>
              <value>org.gjt.mm.mysql.Driver</value></parameter>\\要加载的驱动
            <parameter><name>url</name>
              <value>jdbc:mysql://172.20.0.73/rk?</value></parameter>\\要连接的URL
          </ResourceParams>
         
   </Context>

具体q有一些详l的选项例如QMaxActive{,参加Server.xml中说?/P>

另外在Web.xml中加入如下内容:
<description>test connection</description>\\描述
    <res-ref-name>jdbc/testDB</res-ref-name>\\名称与上对应
    <res-type>javax.sql.DataSource</res-type>\\与上对应
    <res-auth>Container</res-auth>\\与上一|?BR>    </resource-ref>

配置以上内容后,只要在你的Jsp或Javabean 中按以下方式创徏q接Q就可以

Context ctx=new InitialContext();
  DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/testDB");
  conn = ds.getConnection();

以上代码均测试成功,但是在Server.xml中配|数据库的URL中我不能加入useUnicode=true&characterEncoding=GBKQ所以从数据库中取出来的汉字都是Q?Q?

刚刚解决了上面的问题Q可以这样加?/STRONG>

jdbc:mysql://172.20.0.73/rk?useUnicode=true&amp;characterEncoding=GBK

因ؓ&是特D字W?/STRONG>

我用如下代码来解册个问题:

public static String toChinese(String strvalue) {
  try{
   if(strvalue==null)
  {
  return null;
  }
  else {
   strvalue = new String(strvalue.getBytes("ISO8859_1"), "GBK");
   return strvalue;
  }
  }catch(Exception e){
   return null;
  }
 }

写Blog 的时候停了几ơ电Q真是郁P数据库的q接池的概念我现在还是不太清晎ͼ加强学习Q看书去了1



rkind 2005-10-27 13:03 发表评论
]]>
把Sql2000中的表导入到Mysql中的Ҏ http://www.aygfsteel.com/rkind/archive/2005/10/27/17023.htmlrkindrkindThu, 27 Oct 2005 05:03:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17023.htmlhttp://www.aygfsteel.com/rkind/comments/17023.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17023.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17023.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17023.html前两天得C一个成l的数据库,可是是DBF的,因ؓ惛_Mysql环境中做一个成l分析,可是没办法导?/P>

Q于是先导入SQlsever2000中,想生成SQL脚本Q然后再在Mysql Front中改入。SQL文gQ可是发现导出来的脚本只有创的SQL脚本Q没有数据的脚本Q无奈,

后来又想找个软g试一下,下了一个什么DBF To Mysql 在未破解的情况下Q只可以导入Q行数据Q!汗)

用了破解补丁以后导入的时候出错,软g上说库限制的是8MQ可是我的库只有QM多一点,试了几次也不?/P>

然后只好l箋用Sql2000试,选导出的时候发现可以选择导出文本和CSV文gQ而在我的MYsqlfront里面支持?/P>

入CSV文gQ于是先用SQl2000导出文本文gQ把后缀名改为CSvQ再从Mysql中一导入OKQ?/P>

后来在用中才发玎ͼ用这U方法导入以后,有的是Charcd的字D在Mysql front中被认ؓ是Intcd的,

可是在Phpmyadmin中字D|C正常?/P>

rkind 2005-10-27 13:03 发表评论
]]>
一个数据库的小问题 http://www.aygfsteel.com/rkind/archive/2005/10/27/17020.htmlrkindrkindThu, 27 Oct 2005 05:02:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17020.htmlhttp://www.aygfsteel.com/rkind/comments/17020.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17020.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17020.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17020.html今天做了一个新M传的面Q遇C些问?/P>

首先是数据库的设计,考虑新闻有一个优先的问题,因些我在表中需要设|一个recommand的字D,我想设成一个布类型,可是发现在mysql里面没有q种cdQ查查了都推荐用ENUMq种cdQ可以设|两个?/P>

一个设成true一个设成falseQ然后我在JSP中就可以通过Insert一个布值往q个字段传|

今天在表单中使用了单选框Q原来以为需要用request.getparameterValusQ后来发C?/P>

最后在上传新闻的过E中Qtomcat提示一个叫invalid column 什?key的错误,调试了很多次才发现是表中?/P>

有一个ID 的主建,本来是自动增长的Q可是死了几ơ机Q居然变成不是自动增长的Q狂?/P>

q几天电压L不够Q一天死很多ơ机Q搞的现在一个劲按ctrl+s



rkind 2005-10-27 13:02 发表评论
]]>
解决当FORM的ENCTYPE="multipart/form-data" 时request.getParameter()获取不到值的Ҏ http://www.aygfsteel.com/rkind/archive/2005/10/27/17019.htmlrkindrkindThu, 27 Oct 2005 05:01:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17019.htmlhttp://www.aygfsteel.com/rkind/comments/17019.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17019.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17019.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17019.html今天在原来上传文仉面的基础上,x加一D|件的?/P>

因ؓ同时要上传文Ӟ所以ENCTYPE="multipart/form-data" 必须要加在form里面

可是q样的话Q我再servlet里面用request.getParameter()Ҏ无论如何都只是获得null|

不是一般的郁闷Q百度了一下,有h出现了同L问题可是它用的是jspsmartuploadlg实现文g上传的,

而我用的commons fileuploadlgQ仔l看了一下这个组件的apiQ可是英语太差了Q没有发现相关的信息

我又试用session传递参敎ͼ可是发现有点ȝQ因为在表单提交之时你就得赋lsession表单上它的数|

q似乎要javascriptQ可是偶也不会,

后来只有google了,搜烦了一些中文网,也没有找到资料,试试不限制语aQ呵呵呵Q一大片Q后来被俺发

Cq个

I cannot read the submitter using request.getParameter("submitter") (it returns null). ]

Situation:

javax.servlet.HttpServletRequest.getParameter(String) returns null when the ContentType is multipart/form-data

Solutions:

Solution A:

1. download http://www.servlets.com/cos/index.html
2. invoke getParameters() on com.oreilly.servlet.MultipartRequest

Solution B:

1. download http://jakarta.apache.org/commons/sandbox/fileupload/
2. invoke readHeaders() in 
org.apache.commons.fileupload.MultipartStream

Solution C:

1. download http://users.boone.net/wbrameld/multipartformdata/
2. invoke getParameter on 
com.bigfoot.bugar.servlet.http.MultipartFormData

Solution D:

Use Struts. Struts 1.1 handles this automatically.
说是不详l,接着往下看Q另一U解x?/PRE>
> Solution B:
> 1. download
> http://jakarta.apache.org/commons/sandbox/fileupload/
> 2. invoke readHeaders() in
> org.apache.commons.fileupload.MultipartStream

The Solution B as given by my dear friend is a bit hectic and a bit complex :(
We can try the following solution which I found much simpler (at least in usage).

1. Download one of the versions of UploadFile from http://jakarta.apache.org/commons/fileupload/
2. Invoke parseRequest(request) on org.apache.commons.fileupload.FileUploadBase which returns list of org.apache.commons.fileupload.FileItem objects.
3. Invoke isFormField() on each of the FileItem objects. This determines whether the file item is a form paramater or stream of uploaded file.
4. Invoke getFieldName() to get parameter name and getString() to get parameter value on FileItem if it's a form parameter. Invoke write(java.io.File) on FileItem to save the uploaded file stream to a file if the FileItem is not a form parameter.

按照上面的步骤来Q果然一切都okQGQOQLQ真不错Q主要是getFieldName和getStringQ?/PRE>
虽然说这U做法有一炚w烦,但稍微判断加工一下,L获取不到?BR>


rkind 2005-10-27 13:01 发表评论
]]>JAVA中文问题解决ȝ http://www.aygfsteel.com/rkind/archive/2005/10/27/17018.htmlrkindrkindThu, 27 Oct 2005 05:00:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17018.htmlhttp://www.aygfsteel.com/rkind/comments/17018.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17018.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17018.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17018.html
一、JSP面昄q
下面的显C页?display.jsp)出Cؕ码:
<html>
<head>
<title>JSP的中文处?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<%
out.print("JSP的中文处?);
%>
</body>
</html>
对不同的WEB服务器和不同的JDK版本Q处理结果就不一栗原因:服务器用的~码方式不同和浏览器对不同的字符昄l果不同而导致的。解军_法:在JSP面中指定编码方?gb2312),卛_面的第一行加上:<%@ page contentType="text/html; charset=gb2312"%>Q就可以消除q了。完整页面如下:
<%@ page contentType="text/html; charset=gb2312"%>
<html>
<head>
<title>JSP的中文处?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<%
out.print("JSP的中文处?);
%>
</body>
</html>

二、表单提交中文时出现q
下面是一个提交页?submit.jsp)Q代码如下:
<html>
<head>
<title>JSP的中文处?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<form name="form1" method="post" action="process.jsp">
<div align="center">
<input type="text" name="name">
<input type="submit" name="Submit" value="Submit">
</div>
</form>
</body>
</html>
下面是处理页?process.jsp)代码Q?
<%@ page contentType="text/html; charset=gb2312"%>
<html>
<head>
<title>JSP的中文处?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<%=request.getParameter("name")%>
</body>
</html>
如果submit.jsp提交英文字符能正显C,如果提交中文时就会出Cؕ码。原因:览器默认用UTF-8~码方式来发送请求,而UTF-8和GB2312~码方式表示字符时不一Pq样出C不能识别字符。解军_?通过request.seCharacterEncoding("gb2312")对请求进行统一~码Q就实现了中文的正常昄。修改后的process.jsp代码如下Q?
<%@ page contentType="text/html; charset=gb2312"%>
<%
request.seCharacterEncoding("gb2312");
%>
<html>
<head>
<title>JSP的中文处?lt;/title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<%=request.getParameter("name")%>
</body>
</html>

三、数据库q接出现q
只要涉及中文的地方全部是qQ解军_法:在数据库的数据库URL中加上useUnicode=true&characterEncoding=GBKOK了?

四、数据库的显CZؕ?
在mysql4.1.0?varcharcdQtextcd׃出现中文qQ对于varcharcd把它设ؓbinary属性就可以解决中文问题Q对于textcdp用一个编码{换类来处理,实现如下Q?
public class Convert {
/** 把ISO-8859-1码{换成GB2312
*/
public static String ISOtoGB(String iso){
String gb;
try{
if(iso.equals("") || iso == null){
return "";
}
else{
iso = iso.trim();
gb = new String(iso.getBytes("ISO-8859-1"),"GB2312");
return gb;
}
}
catch(Exception e){
System.err.print("~码转换错误Q?+e.getMessage());
return "";
}
}
}
把它~译成classQ就可以调用Convertcȝ静态方法ISOtoGB()来{换编码?


如果你还有什么不懂之处:我给大家推荐一个好的JSP-JAVA|站Q?

http://www.phy.hbnu.edu.cn/dsp/

Linux和Java是互联网的宠?更是互联|时代的两头雄师, Linux的网l安全性和开放源代码,Java的^台独立性和安全易用性,正好W合Internetq_的要求,Linux和Java真是天生一寚wx鸯。双狮资源网l你提供了最好的Linux和Java学习资源Q?Ƣ迎大家多多讉Kq宣传:
http://www.phy.hbnu.edu.cn/dsp/


rkind 2005-10-27 13:00 发表评论
]]>
今天学习java的一Ҏ?http://www.aygfsteel.com/rkind/archive/2005/10/27/17015.htmlrkindrkindThu, 27 Oct 2005 04:59:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17015.htmlhttp://www.aygfsteel.com/rkind/comments/17015.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17015.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17015.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17015.html1

java中当前日期的获取Ҏ

旧方法(已不常用Q:

int year = 0;

int month = 0;

int day = 0;

java.util.Date now = new java.util.Date();

year = now.getYear() + 1900;

month = now.getMonth() + 1;

day = now.getDate();

 

 

新方法:

SimpleDateFormat formatter = new SimpleDateFormat(“yyyy-mm-dd?;

Calendar cal_today = Calendar.getInstance();

int m_day = cal_today.get(cal_today.DAY_OF_MONTH);

int m_month = cal_today.get(cal_today.MONTH) + 1;

int m_hour = cal_today.get(cal_today.HOUR_OF_DAY);

int m_minute = cal_today.get(cal_today.MINUTE);

String d = formatter.format(cal_today.getTime());

 

我采用前一U方法实C按日期生成文件夹.

2

jsp传给mysql当前pȝ旉的方?/P>

insert into youDB(date) values(NOW())

不过q样只能获得当前日期

3 

判断要徏立的文gҎ否存?如果不则新徏立一个文件夹

int year,mm,dd;
  String month,day;
  Date d1=new Date();
  year=d1.getYear()+1900;
  mm=d1.getMonth()+1;
  if (mm<10) month="0"+mm;
  else month=""+mm;
  dd=d1.getDate();
  if (dd<10) day="0"+dd;
  else day=""+dd;
  String filepath="d:\\upload"+"\\"+year+month+day+"\\";
  
  if(!new File(filepath).isDirectory())
        new File(filepath).mkdirs();



rkind 2005-10-27 12:59 发表评论
]]>
jdbcW记5 http://www.aygfsteel.com/rkind/archive/2005/10/27/17008.htmlrkindrkindThu, 27 Oct 2005 04:53:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17008.htmlhttp://www.aygfsteel.com/rkind/comments/17008.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17008.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17008.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17008.html


从前面的学习中,我们掌握了通过Statementcd其子cM递SQL语句Q对数据库管理系l进行访问。一般来_Ҏ据库的操作大部分都是执行查询语句。这U语句执行的l果是返回一个ResultSetcȝ对象。要x查询的结果返回给用户Q必dResultSet对象q行相关处理。今天,我们来学习对结果集的处理方法?BR>
按照惯例Q让我们先来看一个例子:



package com.rongji.demo;



import java.sql.*;



public class dataDemo {

public dataDemo() {

}



public static void main(String[] args) {



try {

Class.forName("oracle.jdbc.driver.OracleDriver");

//建立q接

//W二步是用适当的驱动程序连接到DBMSQ看下面的代码[自行修改您所q接的数据库相关信息]Q?BR>
String url = "jdbc:oracle:thin:@192.168.4.45:1521:oemrep";

String username = "ums";

String password = "rongji";

//用url创徏q接

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

Statement sta = con.createStatement();

String sql = "select * from rbac_application ";

ResultSet resultSet = sta.executeQuery(sql);

while (resultSet.next()) {

int int_value = resultSet.getInt(1);

String string_value = resultSet.getString(2);

String a = resultSet.getString(3);

String b = resultSet.getString(4);

//从数据库中以两种不同的方式取得数据?BR>
System.out.println(int_value + " " + string_value + " " + a + " " +

b);

//检索结果在用户览器上输出?BR>
}

//获取l果集信?BR>
ResultSetMetaData resultSetMD = resultSet.getMetaData();

System.out.println("ColumnCount:" + resultSetMD.getColumnCount());

for (int i = 1; i < resultSetMD.getColumnCount(); i++) {

System.out.println("ColumnName:" + resultSetMD.getColumnName(i) + " " +

"ColumnTypeName:" +

resultSetMD.getColumnTypeName(i));

System.out.println("isReadOnly:" + resultSetMD.isReadOnly(i)

+ " isWriteable:" + resultSetMD.isWritable(i)

+ " isNullable:" + resultSetMD.isNullable(i));

System.out.println("tableName:" + resultSetMD.getTableName(i));

}



//关闭

con.close();

}

catch (Exception ex) {

ex.printStackTrace();

}

}

}



1、ResultSetcȝ基本处理Ҏ



一个ResultSet对象对应着一个由查询语句q回的一个表,q个表中包含所有的查询l果,实际?我们可以将一个ResultSet对象看成一个表。对ResultSet对象的处理必逐行q行,而对每一行中的各个列,可以按Q何顺序进行处理?BR>
ResultSet对象l持一个指向当前行的指针。最?q个指针指向W一行之前。Resultcȝnext()Ҏ使这个指针向下移动一行。因?W一ơ用next()Ҏ指针指向结果集的第一行,q时可以对第一行的数据q行处理。处理完毕后Q用next()ҎQ将指针Ud下一行,l箋处理W二行数据。next()Ҏ的返回值是一个boolean型的|该D为true, 说明l果集中q存在下一条记录,q且指针已经成功指向该记录,可以对其q行处理Q若q回值是false,则说明没有下一行记录,l果集已l处理完毕?BR>
在对每一行进行处理时Q可以对各个列按L序q行处理。不q,按从左到右的序对各列进行处理可以获得较高的执行效率QResultSetcȝgetXXX()Ҏ可以从某一列中获得索结果。其中XXX是JDBC中的Java数据cdQ如int, String ,Date{,q与PreparedStatementcdCallableStatementc设|SQL语句参数值相cM?Sun公司提供的getXXX() API提供两种Ҏ来指定列名进行检索:一U是以一个intg为列的烦引,另一U是以一个String对象作ؓ列名来烦引。大家可以参照一下上面的例子?BR>


2、获取结果集的信?BR>


在对数据库的表结构已l了解的前提下,可以知道q回的结果集中各个列的一些情况,如:列名数据cd{等。有时ƈ不知道结果集中各个列的情况,q时可以使用ResultsetcȝgetMetaDataҎ来获取结果集的信息。如上面的例?

ResultSetMetaData resultSetMD = resultSet.getMetaData();

GetMetaData()Ҏq回一个ResultSetMetaDatacȝ对象Q用该cȝҎQ得到许多关于结果集的信息,下面l出几个常用的方法:

(1) getColumnCount()q回一个int|指出l果集中的列数?BR>
(2) getTableName(int column)q回一个字W串Q指出参C所代表列的表的名称?

(3) getColumnLabel(int column)q回一个String对象Q该对象是column所指的列的昄标题?BR>
(4) getColumnNameQint columnQ返回的是该列在数据库中的名U。可以把此方法返回的String对象作ؓResultsetcȝgetXXX()Ҏ的参数。不q,q没有太大的实际意义?BR>
(5) getColumnType(int comlumn)q回指定列的SQL数据cd。他的返回值是一个int倹{在java.sql.TypescM有关于各USQL数据cd的定义?BR>
(6) getColumnTypeName(int comlumn)q回指定列的数据cd在数据源中的名称。他的返回值是一个String对象?BR>
(7) isReadOnly(int column) q回一个boolean|指出该列是否是只ȝ?BR>
(8) isWriteable(int column) q回一个boolean|指出该列是否可写?BR>
(9) isNullableQint columnQ返回一个boolean|指出该列是否允许存入一个NULL 倹{?BR>

rkind 2005-10-27 12:53 发表评论
]]>
jdbc 学习W记3(PreparedStatement对象) http://www.aygfsteel.com/rkind/archive/2005/10/27/17006.htmlrkindrkindThu, 27 Oct 2005 04:52:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17006.htmlhttp://www.aygfsteel.com/rkind/comments/17006.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17006.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17006.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17006.html


前面Q我们讨Z用连接对象Connection产生Statement对象Q然后用Statement与数据库理pȝq行交互。Statement对象在每ơ执行SQL语句旉该语句传递给数据库。在多次执行同一语句Ӟq样做效率较低。解册个问题的办法是用PreparedStatement对象。如果数据库支持预编译,可以在创建PreparedStatement对象时将SQL语句传递给数据库做预编译,以后每次执行q个SQL语句Ӟ速度可以提高很多。如果数据库不支持预~译Q则在语句执行时Q才其传给数据库。这对于用户来说是完全透明的?BR>
PreparedStatement对象的SQL语句q可以接受参数。在语句中指出需要接受那些参敎ͼ然后q行预编译。在每一ơ执行时Q可以将不同的参C递给SQL语句Q大大提高了E序的效率与灉|性。一般情况下Q用PreparedStatement对象都是带输入参数的?BR>


Z更好的理解,L下面q个例子Q?BR>


package com.rongji.demo;



import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

import java.sql.DatabaseMetaData;

import java.sql.PreparedStatement;





public class DataConn {

public DataConn() {

}

public static void main(String[] args) {

try

{

//加蝲驱动E序

//下面的代码ؓ加蝲JDBD-ODBC驱动E序

Class.forName("oracle.jdbc.driver.OracleDriver");

//建立q接

//W二步是用适当的驱动程序连接到DBMSQ看下面的代码[自行修改您所q接的数据库相关信息]Q?BR>
String url="jdbc:oracle:thin:@192.168.4.45:1521:oemrep";

String user = "ums1";

String password = "rongji";

//用url创徏q接

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

//当前的表中有如下几个字段QID,NAME,PASSWORD,TEXT,NOTE

PreparedStatement insertStatement = con.prepareStatement(

"INSERT INTO rbac_application values(?,?,?,?,?)");

insertStatement.setInt(1,10);

insertStatement.setString(2,"thinkersky");

insertStatement.setString(3,"88888");

insertStatement.setString(4,"q是个测试的应用E序");

insertStatement.setString(5,"备注");

int result = insertStatement.executeUpdate();

System.out.println("the result is" + result);

con.close();

}

catch (Exception e)

{

//输出异常信息

System.err.println("SQLException :"+e.getMessage());

e.printStackTrace();

}

}

}



怿通过q个例子Q对PreparedStatementq个cȝ应用应该有了初步的了解。恩Q让我详l介l一下这个例子吧Q)

1?创徏一个PreparedStatement对象



PreparedStatementcLStatementcȝ子类。同StatemetncMPPreparedStatementcȝ对象也是建立在Connection对象之上的。如下所C:

PreparedStatement insertStatement = con.prepareStatement(

"INSERT INTO rbac_application values(?,?,?,?,?)");

创徏该PreparedStatement对象Ӟ相应的插入记录的SQL语句已经被传递到数据库管理系l中q行预编译?BR>


2?为PreparedStatement对象提供参数



如果以带输入参数的SQL语句形式创徏了一个PreparedStatement对象Q绝大多数情况下都是如此Q。在SQL语句被数据库理pȝ正确执行之前Q必Mؓ参数Q也是SQL语句中是?’的地方Q进行初始化。初始化的方法是调用PreparedStatementcȝ一pdsetXXX()Ҏ。如果输入参数的数据cd是int型,则调用setInt()ҎQ如果输入参数是String型,则调用setString()Ҏ。一般说来,Java中提供的单和复合数据cdQ都可以扑ֈ相应的setXXX()Ҏ?BR>
现在Q让我们再回头看看我们例子中对几个参数的初始化情况:

insertStatement.setInt(1,10);

insertStatement.setString(2,"thinkersky");

insertStatement.setString(3,"88888");

insertStatement.setString(4,"q是个测试的应用E序");

insertStatement.setString(5,"备注");

q里QsetXXX()Ҏ一般有两个参数Q第一个参数都是int型,该参数指CJDBC PreparedStatement对象的第几个参数要被初始化。第二个参数的值就是PreparedStatemetn要被初始化的参数取|数据cd自然也就相同。这里要说明的是当PreparedStatement的一个对象的参数被初始化以后Q该参数的g直保持不变,直到他被再一ơ赋gؓ止?BR>


3?调用PreparedStatement对象的executeUpdate()Ҏ



q里Q要清楚PreparedStatement对象的executeUpdateQ)Ҏ不同于Statement对象的executeUpdate()ҎQ前者是不带参数的,其所需要的SQL语句型的参数已经在实例化该对象时提供了。另外,executeUpdate()Ҏ返回一个整敎ͼq个整数代表executeUpdate()Ҏ执行后所更新的数据库中记录的行数。执行完上面的例子,其结果返回ؓ1。那么什么情况下q回0呢?其实啊,当PreparedStatement对象的executeUpdate()Ҏ的返回值是0时。有两种可能Q?BR>
(1) 所执行的SQL语句是对数据库管理系l的记录q行操作Qƈ且没有记录被 更新

(2) 所执行的SQL语句是对数据库管理系l的表、视囄对象q行操作的DDL语言Q没有数据记录被直接修改?BR>

rkind 2005-10-27 12:52 发表评论
]]>
jdbcW记?关于数据cd http://www.aygfsteel.com/rkind/archive/2005/10/27/17007.htmlrkindrkindThu, 27 Oct 2005 04:52:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17007.htmlhttp://www.aygfsteel.com/rkind/comments/17007.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17007.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17007.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17007.html
表SQL到Java数据cd影射?BR>
SQL 数据cd
JAVA数据cd

CHAR
String

VARCHAR
String

LONGVARCHAR
String

NUMERIC
java.math.BigDecimal

DECIMAL
java.math.BigDecimal

BIT
Boolean

TINYINT
Byte

SMALLINT
Short

INTEGER
Int

BIGINT
Long

REAL
Float

FLOAT
Double

DOUBLE
Double

BINARY
byte[]

VARBINARY
byte[]

LONGVARBINARY
byte[]

DATE
java.sql.Date

TIME
java.sql.Time

TIMESTAMP
java.sql.Timestamp














Java到SQL数据cd影射?BR>
JAVA数据cd
SQL 数据cd

String
VARCHAR or LONGVARCHAR

java.math.BigDecimal
NUMERIC

Boolean
BIT

Byte
TINYINT

Short
SMALLINT

Int
INTEGER

Long
BIGINT

Float
REAL

Double
DOUBLE

byte[]
VARBINARY or LONGVARBINARY

java.sql.Date
DATE

java.sql.Time
TIME

java.sql.Timestamp
TIMESTAMP




q里Q大伙要注意了,q不是所有的数据cd在各U数据库理pȝ中都被支持。下面,几U常用的数据cd之间的{化进行说明:



Q?Q?CHAR, VARCHAR, ?LONGVARCHAR



在SQL语言中,有三U分别表CZ同长度的字符cdCHAR, VARCHAR, ?LONGVARCHARQ在Java/Jsp中ƈ没有相应的三U不同的数据cd与之一一对应QJDBC的处理方法是其与String或者char[]对应h。在实际~程中不必对着三种SQL数据cdq行区分Q全部将他们转化为Sting或者char[]可以了。而且通常使用应用的非常普遍的Stringcd。我们还可以利用StringcL供的Ҏ一个String对象转化为char[],或者用char[]为参数构造一个Stirng对象?BR>
对于定长度的SQL数据cdCHAR(n)Q当从数据库理pȝ中获得的l果集提取该cd的数据时QJDBC会ؓ其构造一个长度ؓn的String对象来代表他Q如果实际的字符个数不’n?pȝ会自动ؓString对象补上I格。当向数据库理pȝ写入的数据类型应该是CHAR(n)ӞJDBC也会该String对象的末补上相应数量的I格?BR>
一般情况下QCHAR, VARCHAR, LONGVARCHAR和String之间可以无差错的q行转换。但非常值得注意的是LONGVARCHARQ这USQL的数据类型有时在数据库中代表的数据可能有几兆字节的大,过了String对象的承受范围。JDBC解决的办法是用Java的Input Stream来接受这U类型的数据[以后我们回涉及到]。Input Stream不仅支持ASCII,而且支持UnicodeQ我们可以根据需要进行选择?BR>


Q?Q?DECIMAL ?NUMERIC



SQL的DECIMAL ?NUMERIC通常用来表示需要一定精度的定点数。在Java的简单数据类型中Q没有一U类型与之相对应。但从JDK1.1开始,Sun公司在java.math.*包中加入了一个新的类BigDecimalQ该cȝ对象可以与DECIMAL 、NUMERICq行转换?BR>
另外Q当从数据库理pȝ中读取数据时Q还可以用getString()Ҏ来获取DECIMAL ?NUMERIC?BR>


Q?Q?BINARY, VARBINARY, ?LONGVARBINARY



在编E时无须_区分q三USQL数据cdQJDBC他们统一影射为byte[]。其中LONGVARBINARY和LONGVARCHAR怼Q可以代表几兆字节的数据Q超出数l的承受范围。解决的办法依然是用Input Stream来接受数据?



Q?Q?BIT



代表一个二q制位的BITcd被JDBC影射为boolean型?BR>


Q?Q?TINYINT, SMALLINT, INTEGER, ?BIGINT



SQL语言的TINYINT, SMALLINT, INTEGER, ?BIGINT分别代表8位?6位?2位?4位的数据。他们分别被影射为Java的byte, short, int, ?long



Q?Q?REAL, FLOAT, ?DOUBLE



SQL定义了REAL, FLOAT, DOUBLE来支持QҎ。JDBCREAL影射到Java的float,FLOAT,DOUBLE影射到java的double?BR>


Q?Q?DATE, TIME, ?TIMESTAMP



SQL定义了三U和日期相关的数据类型?DATE代表q、月、日QTIME代表时、分、秒QTIMESTAMPl合了DATE和TIME的全部信息,而且增加了更加精的旉计量单位?BR>
在java的标准类库中Qjava.util.*包中的Datecȝ来表C日期和旉。但是该cdSQL中的DATE, TIME, ?TIMESTAMP直接影射关系q不清晰。ƈ且,该类也不支持TIMESTAMP的精时间计量单位。因此,Sun公司在java.sql.*中ؓjava.util.Date增加了三个子c:java.sql.DateQjava.sql.Time Qjava.sql.TimestampQ分别与SQL中的三个日期数据cd相对应?BR>


MQ关于SQL与JAVA之见数据cd的{化,q有很多l节斚w的东西,q里׃一一介绍了,有需要的朋友自己可以L一下相x档。这里给大家介绍一个我常去的网站:

http://java.sun.com/docs/books/tutorial/jdbc?BR>

rkind 2005-10-27 12:52 发表评论
]]>
JDBC学习W记1 http://www.aygfsteel.com/rkind/archive/2005/10/27/17004.htmlrkindrkindThu, 27 Oct 2005 04:51:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/17004.htmlhttp://www.aygfsteel.com/rkind/comments/17004.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/17004.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/17004.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/17004.html


Q?Q加载特定的JDBC驱动E序



Z与特定的数据源连接,JDBC必须加蝲相应的驱动程序。这些驱动程序都是通过语句QClass.forName("Driver Name"); 来加载的。这里面有一个小技巧,我们可以在”Driver Name”出填入一pd的驱动程序名Uͼ例如Q“Class.forName("sun.jdbc.odbc.JdbcOdbcDriverQoracle.jdbc.driver.OracleDriver?; 中间用冒号隔开。JSP按照列表顺序搜索驱动程序,q且加蝲W一个能与给定的URL相连的驱动程序。在搜烦驱动E序列表ӞJSP蟩q包含不可信M码的驱动E序Q除非他与要打开的数据库理pȝ是来源于同一?



Q?Q用已注册的驱动E序建立到数据库理pȝ的连?BR>


我们要做的第二步是用已经注册的驱动程序徏立到数据库管理系l的q接Q这要通过DriverManagercȝgetConncetionҎ来实现。这里特别需要注意的是Stringcd url 参数的取|url代表一个将要连接的特定的数据库理pȝ的数据源。用不同的数据库驱动程序,url的取值方式是不同的。例E中加蝲了“com.mysql.jdbc.Driver”驱动,url的取值方式“jdbc:mysql://localhost:3306/ums_db?useUnicode=true&amp;characterEncoding=GB2312”,如果加蝲“oracle.jdbc.driver.OracleDriver”驱动,url的取值方式应该是“jdbc:oracle:thin:@host name:port number:service name”。其他驱动程序的url的取值方式,各位自行参阅相应的文挡?BR>
例程中的GetConnection()Ҏ只有一个参数String urlQ代表ODBC数据源,如果q接大型数据库,则需要三个参敎ͼString url、Strng user、String password。User和password代表数据库管理系l的用户名和口o。一般的大型数据库如Oracle、MS SQL Server、DB2{用户名和口令是必须的。而小型的数据库如ACCESS、Foxpro{ƈ不需要?BR>
如果q接成功Q则会返回一个Connectioncȝ对象con。以后对数据库的操作都是建立在con对象的基上的。GetConnection()Ҏ是DriverManagercȝ静态方法,使用时不用生成DriverManagercȝ对象Q直接用类名DriverManager可以调用?



Q?Q创建Statement声明Q执行SQL语句



在实例化一个Connectioncȝ对象conQ成功徏立一个到数据库管理系l的q接之后。我们要做的W三步是利用该con对象生成一个Statementcȝ对象stmt。该对象负责SQL语句传递给数据库管理系l执行,如果SQL语句产生l果集,stmt对象q会结果集q回l一个ResultSetcȝ对象?BR>
Statementcȝ主要的方法有三个Q?BR>
executeUpdate(String sql)

executeQuery(String sql)

execute(String sql)

executeUpdate(String sql)Ҏ用于执行DDLcd的SQL语句Q这U类型的SQL语句会对数据库管理系l的对象q行创徏、修攏V删除操作,一般不会返回结果集?BR>


executeQuery(String sql)Ҏ用于执行一条查询数据库的SELECT语句。如果有W合查询条g的数据存在,该方法将q回一个包含相应数据的ResultSetcd象,否则Q该对象的next()Ҏ返回false?BR>


execute(String sql)Ҏ用于执行一个可能返回多个结果集的存储过E(Stored ProcedureQ或者一条动态生成的不知道结果集个数的SQL语句。如果存储过E或者SQL语句产生一个结果集Q该Ҏq回false.如果产生多个l果集,该方法返回true。我们可以综合运用StatementcȝgetResultSet(), getUpdateCount(), getMoreResults()Ҏ来检索不同的l果集?BR>
服务器对JSPE序q行~译Ӟq不对将要执行的SQL语句作语法检查,只是其作ؓ一个String对象。只有当客户端发出HTTPhQJava虚拟机对Servletq行解释执行Q将SQL语句传递给数据库管理系l时Q才能知道他是否正确。对于错误的SQL语句Q在执行时会产生SQLExcepion。其实,所有与JDBC操作的JSP语句都与数据库管理系l及相应的驱动程序有养I是超出JSP的控制范围的。这些语句只有在实际的解释执行中才能验出是否能顺利执行,因此一定要声明q捕获例外:

try{

?

}catch(SQLException e)

{

Sytem.err.println(“SQLException:?e.getMessage());

}

否则QJSPE序无法被编译成Servlet?BR>


Q?Q关闭Statement对象



一个Statement对象在打开后可以多ơ调用executeQuery(String sql)、executeUpdate(String sql)、execute(String sql)Ҏ来执行SQL语句Q与数据库管理系l进行交互。但一个Statement对象在同一旉只能打开一个结果集Q对W二个结果集的打开隐含着对第一个结果集的关闭。如果想对多个结果集同时q行操作Q必d建多个Statement对象Q在每个Statement对象上执行SQL语句获得相应的结果集?BR>


Q?Q关闭Connection对象



在处理完Ҏ据库的操作后Q一定要Connection对象关闭Q以释放JDBC占用的系l资源。在不关闭Connection对象的前提下再次用DriverManager静态类初始化新的Connection对象会生系l错误。而一个已l徏立连接的Connection对象可以同时初始化多个Statement对象。对应不同的数据库管理系l的Connection对象可以初始化Statement对象的个数是不同的。在Oracle中是50个?BR>

rkind 2005-10-27 12:51 发表评论
]]>
java q接到远Emysql数据?/title><link>http://www.aygfsteel.com/rkind/archive/2005/10/27/17003.html</link><dc:creator>rkind</dc:creator><author>rkind</author><pubDate>Thu, 27 Oct 2005 04:49:00 GMT</pubDate><guid>http://www.aygfsteel.com/rkind/archive/2005/10/27/17003.html</guid><wfw:comment>http://www.aygfsteel.com/rkind/comments/17003.html</wfw:comment><comments>http://www.aygfsteel.com/rkind/archive/2005/10/27/17003.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/rkind/comments/commentRss/17003.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/rkind/services/trackbacks/17003.html</trackback:ping><description><![CDATA[<P>首先加蝲mm.mysql2.0.4-bin.jar驱动,q把其加入classpath,注意一定要打开q程mysql的你的主机的讉K权限</P> <P>然后~写如下代码</P> <P>          String name="org.gjt.mm.mysql.Driver";///加蝲jdbc driver<BR>          String url="jdbc:mysql://172.20.0.73/jilei";  //q接?72.20.0.73上的jilei的mysql数据?BR>          Class.forName(name),//创徏c?BR>          con=DriverManager.getConnection(url,"你的username","你的密码")//创徏q接</P> <P>输入以下代码供测试?/P> <P>Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>   String sql="select * from student"; <BR>  ResultSet rs=stmt.executeQuery(sql); <BR> while(rs.next()) { <BR>System.out.println("您的W一个字D内容ؓQ?+rs.getString(1)); <BR>System.out.println("您的W二个字D内容ؓQ?+rs.getString(2) );<BR>System.out.println("您的W三个字D内容ؓQ?+rs.getString(3) );<BR>} <BR>  rs.close();<BR>  stmt.close();<BR>          con.close();</P><img src ="http://www.aygfsteel.com/rkind/aggbug/17003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/rkind/" target="_blank">rkind</a> 2005-10-27 12:49 <a href="http://www.aygfsteel.com/rkind/archive/2005/10/27/17003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA中正则表辑ּ的应用(二)java.util.regex??http://www.aygfsteel.com/rkind/archive/2005/10/27/16999.htmlrkindrkindThu, 27 Oct 2005 04:44:00 GMThttp://www.aygfsteel.com/rkind/archive/2005/10/27/16999.htmlhttp://www.aygfsteel.com/rkind/comments/16999.htmlhttp://www.aygfsteel.com/rkind/archive/2005/10/27/16999.html#Feedback0http://www.aygfsteel.com/rkind/comments/commentRss/16999.htmlhttp://www.aygfsteel.com/rkind/services/trackbacks/16999.html1.介: 
java.util.regex是一个用正则表达式所订制的模式来对字W串q行匚w工作的类库包?

它包括两个类QPattern和Matcher Pattern 一个Pattern是一个正则表辑ּl编译后的表现模式?nbsp;
Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做ؓ匚w模式对字W串展开匚w查?nbsp;首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经~译后的模式Q然后一个Matcher实例在这个给定的Pattern实例的模式控制下q行字符串的匚w工作?

以下我们分别来看看q两个类Q?

2.Patternc? 
Pattern的方法如下: static Pattern compile(String regex)
给定的正则表达式编译ƈ赋予lPatternc?nbsp;
static Pattern compile(String regex, int flags)
同上Q但增加flag参数的指定,可选的flag参数包括QCASE INSENSITIVE,MULTILINE,DOTALL,UNICODE CASEQ?nbsp;CANON EQ 
int flags()
q回当前Pattern的匹配flag参数. 
Matcher matcher(CharSequence input)
生成一个给定命名的Matcher对象 
static boolean matches(String regex, CharSequence input)
~译l定的正则表辑ּq且对输入的字串以该正则表达式ؓ模开展匹?该方法适合于该正则表达式只会用一ơ的情况Q也是只进行一ơ匹配工作,因ؓq种情况下ƈ不需要生成一个Matcher实例?nbsp; 
String pattern()
q回该Patter对象所~译的正则表辑ּ?nbsp;
String[] split(CharSequence input)
目标字W串按照Pattern里所包含的正则表辑ּ为模q行分割?nbsp;
String[] split(CharSequence input, int limit)
作用同上Q增加参数limit目的在于要指定分割的D|Q如limi设ؓ2Q那么目标字W串根据正则表辑ּ分ؓ割ؓ两段?nbsp;


一个正则表辑ּQ也是一串有特定意义的字W,必须首先要编译成Z个Patterncȝ实例Q这个Pattern对象会使用matcher()Ҏ来生成一个Matcher实例Q接着便可以用该 Matcher实例以编译的正则表达式ؓ基础对目标字W串q行匚w工作Q多个Matcher是可以共用一个Pattern对象的?

现在我们先来看一个简单的例子Q再通过分析它来了解怎样生成一个Pattern对象q且~译一个正则表辑ּQ最后根据这个正则表辑ּ目标字W串q行分割Q?nbsp;
import java.util.regex.*;
public class Replacement{
      public static void main(String[] args) throws Exception {
        // 生成一个Pattern,同时~译一个正则表辑ּ
        Pattern p = Pattern.compile("[/]+");
        //用Pattern的split()Ҏ把字W串?/"分割
        String[] result = p.split(
"Kevin has seen《LEON》seveal times,because it is a good film."
+"/ 凯文已经看过《这个杀手不太冷》几ơ了Q因为它是一?
+"好电影?名词:凯文?);
        for (int i=0; i<result.length; i++)
System.out.println(result[i]);
}
}




输出l果为:

Kevin has seen《LEON》seveal times,because it is a good film.
凯文已经看过《这个杀手不太冷》几ơ了Q因为它是一部好电媄?
名词:凯文?

很明显,该程序将字符串按"/"q行了分D,我们以下再?split(CharSequence input, int limit)Ҏ来指定分D늚D|Q程序改动ؓQ?
tring[] result = p.split("Kevin has seen《LEON》seveal times,because it is a good film./ 凯文已经看过《这个杀手不太冷》几ơ了Q因为它是一部好电媄?名词:凯文?Q?);

q里面的参数"2"表明目标语句分ZDc?

输出l果则ؓQ?

Kevin has seen《LEON》seveal times,because it is a good film.
凯文已经看过《这个杀手不太冷》几ơ了Q因为它是一部好电媄?名词:凯文?

׃面的例子Q我们可以比较出java.util.regex包在构造Pattern对象以及~译指定的正则表辑ּ的实现手法与我们在上一中所介绍的Jakarta-ORO 包在完成同样工作时的差别QJakarta-ORO 包要先构造一个PatternCompilercd象接着生成一个Pattern对象Q再正则表辑ּ用该PatternCompilercȝcompile()Ҏ来将所需的正则表辑ּ~译赋予Patternc:

PatternCompiler orocom=new Perl5Compiler();

Pattern pattern=orocom.compile("REGULAR EXPRESSIONS");

PatternMatcher matcher=new Perl5Matcher();

但是在java.util.regex包里Q我们仅需生成一个Patternc,直接使用它的compile()Ҏ可以达到同L效果:
Pattern p = Pattern.compile("[/]+");

因此gjava.util.regex的构造法比Jakarta-ORO更ؓzƈҎ理解?

3.Matcherc?
MatcherҎ如下Q?Matcher appendReplacement(StringBuffer sb, String replacement)
当前匹配子串替换ؓ指定字符Ԍq且替换后的子串以及其之前Cơ匹配子串之后的字符串段dC个StringBuffer对象里?
StringBuffer appendTail(StringBuffer sb)
最后一ơ匹配工作后剩余的字W串dC个StringBuffer对象里?
int end()
q回当前匚w的子串的最后一个字W在原目标字W串中的索引位置 ?
int end(int group)
q回与匹配模式里指定的组相匹配的子串最后一个字W的位置?
boolean find()
试在目标字W串里查找下一个匹配子丌Ӏ?
boolean find(int start)
重设Matcher对象Qƈ且尝试在目标字符串里从指定的位置开始查找下一个匹配的子串?
String group()
q回当前查找而获得的与组匚w的所有子串内?
String group(int group)
q回当前查找而获得的与指定的l匹配的子串内容
int groupCount()
q回当前查找所获得的匹配组的数量?
boolean lookingAt()
目标字W串是否以匹配的子串起始?
boolean matches()
试Ҏ个目标字W展开匚w,也就是只有整个目标字W串完全匚w时才q回真倹{?
Pattern pattern()
q回该Matcher对象的现有匹配模式,也就是对应的Pattern 对象?
String replaceAll(String replacement)
目标字W串里与既有模式相匹配的子串全部替换为指定的字符丌Ӏ?
String replaceFirst(String replacement)
目标字W串里第一个与既有模式相匹配的子串替换为指定的字符丌Ӏ?
Matcher reset()
重设该Matcher对象?
Matcher reset(CharSequence input)
重设该Matcher对象q且指定一个新的目标字W串?
int start()
q回当前查找所获子串的开始字W在原目标字W串中的位置?
int start(int group)
q回当前查找所获得的和指定l匹配的子串的第一个字W在原目标字W串中的位置?


Q光看方法的解释是不是很不好理解Q不要急,待会l合例子比较容易明白了Q?

一个Matcher实例是被用来对目标字W串q行Z既有模式Q也是一个给定的Pattern所~译的正则表辑ּQ进行匹配查扄Q所有往Matcher的输入都是通过CharSequence接口提供的,q样做的目的在于可以支持对从多元化的数据源所提供的数据进行匹配工作?

我们分别来看看各Ҏ的用:

★matches()/lookingAt ()/find()Q?
一个Matcher对象是由一个Pattern对象调用其matcher()Ҏ而生成的Q一旦该Matcher对象生成,它就可以q行三种不同的匹配查找操作:

matches()Ҏ试Ҏ个目标字W展开匚w,也就是只有整个目标字W串完全匚w时才q回真倹{?
lookingAt ()Ҏ检目标字W串是否以匹配的子串起始?
find()Ҏ试在目标字W串里查找下一个匹配子丌Ӏ?

以上三个Ҏ都将q回一个布值来表明成功与否?

★replaceAll ()/appendReplacement()/appendTail()Q?
Matchercd时提供了四个匹配子串替换成指定字符串的ҎQ?

replaceAll()
replaceFirst()
appendReplacement()
appendTail()

replaceAll()与replaceFirst()的用法都比较单,L上面Ҏ的解释。我们主要重点了解一下appendReplacement()和appendTail()Ҏ?

appendReplacement(StringBuffer sb, String replacement) 当前匹配子串替换ؓ指定字符Ԍq且替换后的子串以及其之前Cơ匹配子串之后的字符串段dC个StringBuffer对象里,而appendTail(StringBuffer sb) Ҏ则将最后一ơ匹配工作后剩余的字W串dC个StringBuffer对象里?

例如Q有字符串fatcatfatcatfat,假设既有正则表达式模式ؓ"cat"Q第一ơ匹配后调用appendReplacement(sb,"dog"),那么q时StringBuffer sb的内容ؓfatdogQ也是fatcat中的cat被替换ؓdogq且与匹配子串前的内容加到sb里,而第二次匚w后调用appendReplacement(sb,"dog")Q那么sb的内容就变ؓfatdogfatdogQ如果最后再调用一ơappendTailQsbQ?那么sb最l的内容是fatdogfatdogfat?

q是有点模糊Q那么我们来看个单的E序Q?
//该例把句子里的"Kelvin"改ؓ"Kevin"
import java.util.regex.*;
public class MatcherTest{
public static void main(String[] args)
throws Exception {
//生成Pattern对象q且~译一个简单的正则表达?Kelvin"
Pattern p = Pattern.compile("Kevin");
//用Patterncȝmatcher()Ҏ生成一个Matcher对象
Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in Kelvin Chen's KelvinSoftShop company");
StringBuffer sb = new StringBuffer();
int i=0;
//使用find()Ҏ查找W一个匹配的对象
boolean result = m.find();
//使用循环句子里所有的kelvin扑ևq替换再内容加到sb?
while(result) {
i++;
m.appendReplacement(sb, "Kevin");
System.out.println("W?+i+"ơ匹配后sb的内ҎQ?+sb);
//l箋查找下一个匹配对?
result = m.find();
}
//最后调用appendTail()Ҏ最后一ơ匹配后的剩余字W串加到sb里;
m.appendTail(sb);
System.out.println("调用m.appendTail(sb)后sb的最l内Ҏ:"+ sb.toString());
}
}



最l输出结果ؓQ?
W?ơ匹配后sb的内ҎQKevin
W?ơ匹配后sb的内ҎQKevin Li and Kevin
W?ơ匹配后sb的内ҎQKevin Li and Kevin Chan are both working in Kevin
W?ơ匹配后sb的内ҎQKevin Li and Kevin Chan are both working in Kevin Chen's Kevin
调用m.appendTail(sb)后sb的最l内ҎQKevin Li and Kevin Chan are both working in Kevin Chen's KevinSoftShop company.

看了上面q个例程是否对appendReplacement()QappendTail()两个Ҏ的用更清楚呢,如果q是不太肯定最好自己动手写几行代码试一下?

★group()/group(int group)/groupCount()Q?
该系列方法与我们在上介l的Jakarta-ORO中的MatchResult .group()ҎcM(有关Jakarta-ORO请参考上的内容)Q都是要q回与组匚w的子串内容,下面代码很好解释其用法Q?
import java.util.regex.*;

public class GroupTest{
public static void main(String[] args)
throws Exception {
Pattern p = Pattern.compile("(ca)(t)");
Matcher m = p.matcher("one cat,two cats in the yard");
StringBuffer sb = new StringBuffer();
boolean result = m.find();
System.out.println("该次查找获得匚wl的数量为:"+m.groupCount());
for(int i=1;i<=m.groupCount();i++){
System.out.println("W?+i+"l的子串内容为: "+m.group(i));
}
}
}



输出为:
该次查找获得匚wl的数量为:2
W?l的子串内容为:ca
W?l的子串内容为:t

Matcher对象的其他方法因比较好理解且׃幅有限Q请读者自qE验证?

4Q一个检验Email地址的小E序Q?
最后我们来看一个检验Email地址的例E,该程序是用来验一个输入的EMAIL地址里所包含的字W是否合法,虽然q不是一个完整的EMAIL地址验程序,它不能检验所有可能出现的情况Q但在必要时您可以在其基上增加所需功能?
import java.util.regex.*;
public class Email {
public static void main(String[] args) throws Exception {
String input = args[0];
//输入的EMAIL地址是否?非法W号"."?@"作ؓ起始字符
Pattern p = Pattern.compile("^\\.|^\\@");
Matcher m = p.matcher(input);
if (m.find()){
System.err.println("EMAIL地址不能?.'?@'作ؓ起始字符");
}
//是否以"www."v?
p = Pattern.compile("^www\\.");
m = p.matcher(input);
if (m.find()) {
System.out.println("EMAIL地址不能?www.'起始");
}
//是否包含非法字W?
p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
m = p.matcher(input);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
boolean deletedIllegalChars = false;
while(result) {
//如果扑ֈ了非法字W那么就设下标记
deletedIllegalChars = true;
//如果里面包含非法字符如冒号双引号{,那么把他们消去Q加到SB里面
m.appendReplacement(sb, "");
result = m.find();
}
m.appendTail(sb);
input = sb.toString();
if (deletedIllegalChars) {
System.out.println("输入的EMAIL地址里包含有冒号、逗号{非法字W,请修?);
System.out.println("您现在的输入? "+args[0]);
System.out.println("修改后合法的地址应类? "+input);
}
}
}



例如Q我们在命o行输入:java Email www.kevin@163.net

那么输出l果会是:EMAIL地址不能?www.'起始

如果输入的EMAIL为@kevin@163.net

则输ZؓQEMAIL地址不能?.'?@'作ؓ起始字符

当输入ؓQcgjmail#$%@163.net

那么输出是Q?

输入的EMAIL地址里包含有冒号、逗号{非法字W,请修?
您现在的输入? cgjmail#$%@163.net
修改后合法的地址应类? cgjmail@163.net

5QȝQ?
本文介绍了jdk1.4.0-beta3里正则表辑ּ?-java.util.regex中的cM及其ҎQ如果结合与上一中所介绍的Jakarta-ORO API作比较,读者会更容易掌握该API的用,当然该库的性能在未来的日子里不断扩展Q希望获得最C息的读者最好到及时到SUN的网站去了解?

6Q结束语Q?
本来计划再多写一介l一下需付费的正则表辑ּ库中较具代表性的作品Q但觉得既然有了免费且优U的正则表辑ּ库可以用,何必q要L需付费的呢Q相信很多读者也是这么想?Q所以有兴趣了解更多其他的第三方正则表达式库的朋友可以自己到|上查找或者到我在参考资料里提供的网址ȝ看?


rkind 2005-10-27 12:44 发表评论
]]>
վ֩ģ壺 | ˮ| ͨ| Ƹ| | Զ| ֹ| | | ۶| | | կ| ƽԶ| ³| | | մ| Ȫ| | ˮ| | ǹ| ƽ| | | ˮ| ƽ| Ϫ| ̽| | ɽ| | | | | ׸| | | | ְ|