----------------------------------------------------------------------------------------------------------------------------------------------------------

 泡牛吧!

                                       希望越来越多的光棍能够泡到牛

-----------------------------------------------------------------------------------------------------------------------------------------------------------

共 40篇 前 9 页:    每页5篇 上一页   下一页  

java





张五常:广州中山大学讲演录


(1)明晰产权和交易费用是理解中国改革的钥匙
  1979年我来广州看我的姐姐。那时候广州晚上全是黑的,街上没有灯;市场上连一只鸡蛋都买不到(笑声),我的姐姐在床底下养鸡(笑声);到外面吃饭很难找到一家好的餐馆,有时候叫了菜也没有白米饭,因为那时候白米是要配给的。那是22年前的事了,在座很多同学可能还没有出世。

  两个多月前的农历新年,我又到广州来,到佛山一家酒家吃午饭。那酒家里有一条食街,你可以随意选购东西让他们煮,有汤水部,有海鲜部,有小炒部,有烧腊部……光是海鲜部里就有六种虾,任君选择,琳琅满目,多得不得了。那酒家全坐满了人。

  22年时间,同样的地方,同样的人,产权制度改了,生活就可以有这么大的变化。如果中国还是70年代那种制度,那就连一只鸡蛋都买不到。所以产权对民生的重要性是显而易见的。

  你们要听清楚,我说的是很简单的东西,这是经济学的基础。在鲁宾逊一人世界里是没有产权的。不需要警察,没有市场,没有银行,没有货币,没有经纪,没有公司,没有律师,只有鲁宾逊一个人。鲁宾逊的经济问题是很容易处理的,两个小时我就可以把你们都教会了。经济学的困难就在于多加了一个人。多了一个人后,两个人就成了社会。社会的定义就是多了一个人(笑声)--我喜欢从简单的角度来看问题。

  两个人都想要同样的物品,竞争就无可避免。有竞争就要决定输赢,这也无可避免。决定输赢就要讲游戏规则。你们打网球有游戏规则,田径也有游戏规则,弱肉强食也是游戏规则,走后门也是游戏规则(笑声)。有了游戏规则后,就可以决定输赢。比如田径的游戏规则是以谁快谁慢来决定输赢。所以竞争一定要决出胜负。

  我们这个社会就是你一早起来就要开始竞争。你去吃早餐,在这社会里就得有人吃得少一些,有人吃得多一些,所以你的早餐也是竞争赢来的。现在的竞争很简单。我是大教授,但我没有优先权;即使我的父亲是政协委员,我也没有优先权;我考试考第一也没有优先权;但我掏出一张钞票来,我就有优先权了(笑声)。你想要个苹果,我也想要同一个苹果,我拿出2元,你不肯拿出2元,我就赢了(笑声)。

  这个用价钱来定胜负的准则,我们要感谢科斯发明的科斯定律:只有明晰产权,才有这种准则;取消了产权,就不会有这种准则。

  你们说我张五常赞成自由市场,但我只是说自由市场对生产增长有利。现在佛山有那么多东西买就是明晰产权的结果嘛。自由市场究竟好不好就很难说了。我只能告诉你自由市场是对经济有贡献的。如果你问我喜欢哪种制度,我喜欢全世界的财富、美女(笑声),全部要用读书考试来分配(笑声、掌声)。

  所以问题在于,决定胜负的准则可以有很多很多,市价只是其中一种。但假如市价不存在的话,或像以前那样是配给的话,那你们就要走后门,或者要排队。排队排上几个小时,然后花几毛钱买条鱼。你排队花的时间是浪费掉的嘛,你站在那里对社会有什么贡献呢?

  但如果鱼的价格是由市场决定的,比如说10元一条,你能拿出10元就是你赢了;你拿不出10元的话就算你是高官的儿子也没用(笑声)。那你会怎么样?你就要去工作,去赚10元来买这条鱼。所以你要拿出10元,你就要对社会做出10元的贡献。

  市场是有交易费用的。你说要有明晰的产权,但明晰产权的界定和保障,都是很贵的。市场的交易会引致多种交易费用,比如说信息的费用、律师的费用、警察的费用。

  在华盛顿州,一个红苹果--我20年前在那里的时候,如果到果园里去买,自己摘--5美分一磅。但如果到市场上买,3毛钱一磅。香港出产的产品,在美国卖1元的话,在香港顶多只能卖1毛9分。在这1毛9分里,其中一半以上是工厂里的经理、秘书的薪金。所以在美国卖1元的产品,在香港的生产费用最多也就是3、4分钱。大部分费用都是交易费用,所以交易费用是很庞大的,你在交易里可以赚到很多钱。

  市场交易可以赚很多钱,大家都获利甚丰。不是赚1倍、2倍、10倍、100倍,也不是1000倍,起码赚1万倍,可能是10万倍,也可能是1亿倍,我也算不清楚。为什么能赚那么多?

  举个例子,1支圆珠笔,1元1支。这支圆珠笔是用塑料制造的,里面是石油工业的油,还有金属在里面,还有一个伟大的发明,那就是有一颗珠子在笔尖那里,可以有很多颜色的变化。现在国内劳动力工资水平,保守估计,是5元人民币1小时。就是说一个普通工人工作1小时就可以买5支圆珠笔。

  但如果要你自己从头发明、制造这支圆珠笔,就算在座的600人??知做起--比如说你们是从一个荒岛出来的--我要你们制造1支圆珠笔,你们600人穷毕生精力也不能制造出来!但是现在就是一个挖路的工人只要挖上12分钟就可以买1支圆珠笔。

  在交易上赚钱,可以有如此大的利益呀!你看看你自己现在穿的衣服,要是你自己来制造怎么能行?自给自足在今天已经是不可能的事情。在我们这个世界自给自足是不可能的,只能在交易上赚很多很多。

  为什么能赚这么多呢?同学通常会说这是"比较优势理论",英文是Comparative Advantage。弗里德曼认为这是最重要的。但我不同意。现在他也同意我了(笑声)。比较优势理论有点帮助,但第一重要的是专业生产,专业生产使学习费用降到很低。大家各自专业生产,然后到市场上交易,大家的利益都很大。

  因为专业化的缘故,就有人去做专业研究。新的发明一出来,几千年都不会消失。你想到一点,他想到一点,日积月累就是很多。我们现在的日常用品,都凝结了许许多多前人的发明。专业研究、专业思想、专业生产,然后大家在市场上交易,大家都赚很多。要做到这一点,就要有市场;要有市场,就要有明晰产权。这就是著名的科斯定律。科斯定律不是你们在外面听到的那个,你们听到的那个是错的(笑声)。对的科斯定律就是:没有明晰产权,就没有市场。就是这么简单。

  产权的定义,是我发明的(笑声),有三个含义:使用权要明晰;收入的享受权要明晰;转让权要自由。所谓有转让权,是包括出租在内,所以使用权不是指一定要我自己使用,而是说使用的决定权是我的。我决定给你用,这也是我的权。当你有了这几个权利,这就是明晰产权的定义。

  举个例子。假如我这手表是值钱的,我要拿出来卖,就要价高者得,你给100元,我就卖给你。但是现在我这手表不卖,你们排队来拿吧。那得到手表的人排队所费的时间就会刚好值100元。但你花这些时间对我来说有什么好处呢?对社会有什么好处呢?

  大凡财产任人取用,就会有这种后果:物品或资源的所值烟消云散。这就是我说的很重要的"租值消散定律"。比如说这个湖里养了鱼,这些鱼是我私人所有的,你去钓可以,给钱吧。但假如那个湖任人垂钓,所有人就会都跑去钓鱼。结果钓鱼所花的时间的价值,等于那些鱼的价值,结果鱼塘的租值等于零。如果鱼塘是公有的话,要不就没鱼在里面,要不就人人去钓,耗费与鱼的价值相抵消。但如果是私人的就不同了。我不会让那么多人去钓,我要收租,那就有租值存在。你要给租金我才给你去钓,我不会让所有人都去钓。

  在任何情况下,人们都会尽量减少租值的消散。其中一种减少租值消散的方法就是明晰产权。那个鱼塘是我的,你要去钓鱼就要付租金给我,你不给钱给我,我不让你钓,这是界定权利的第一种办法。

  第二种办法呢,取消明晰产权,但资源也不是任何人都可以使用的,权利是用等级特权来界定的。县有县的特权,队有队的特权,行政官员分多少级,老师分多少级,非常复杂。这就是用人来界定权利。

  要知道,在这个社会里,人一生下来就是不平等的。坦白地说,这是上帝造成的,怎么可能平等?每个人都不平等。某方面是可以平等的,但不可能每方面都平等。在产权明晰的制度里,每个人拥有的财产都不一样,有人富一点,有人穷一点。但正因为产权不平均,人权就可以平均;人权平均,就可以搞法治,可以搞司法,因为司法就是"法律面前人人平等"。人的资产不平等,但人权可以平等。

  但如果资源以人的特权等级来界定权利,人为界定权利,人权是不平等的,不可能搞司法制度,可以讲纪律,可是不能够讲法律。怎么可能讲法律呢?高官的儿子犯法,跟我的儿子犯法,处分就不同。你不能说这种制度不好,只能说这种制度是与明晰产权制度不同的。

  自由市场的交易费用很大,但交易利益也很大。中国改革之前,交易费用很大,虽然没什么交易。交易费用是指在鲁宾逊一人世界里没有的费用,所以根据这个定义,搞人际关系是交易费用,走后门也是交易费用,交易费用非常大。

  所以在国民收入里交易费用的百分比只要跌一点点,就会富有很多;但只要上升一点点,就会变得很穷。从这个角度来看,过去中国的交易费用占国民总收入的比例非常高。我1979年回中国时,看到那些人上班时从早到晚就在谈论怎么拉关系,到什么地方才能买到一只鸡蛋,可见当时交易费用占的百分比一点也不低。所以中国改了一个制度,交易费用百分比减少了,一下子就富了很多。

  交易费用对人的生活当然是不好的。我上面那个定义,弗里德曼看了,也觉得是最好的一个。总之,交易费用占国民收入百分比越低越好。

  (2)中国的改革还应该更快些

  中国的改革就是要把按人的等级来排列的制度改变为按资产排列的制度,这是重点所在。但这是非常困难的,中国已经算是做得相当好了。我在1981年写书推断中国改革的发生。我知道一定会有这种转变,但我没想到转变会这么快。但??,我还是希望它能改变得更快。

  很多人赞成渐进,比如说斯坦福大学的刘遵义、钱颖一都赞成渐进。可是我不同意。他们理论上分析出来要渐进,但他们不明白这个世界。渐进有很大的问题,一定要急进。大致来说界定权利有三种方法,不是两种。一种是以人的等级特权来界定权利,改革前的中国就是那种;一种是以明晰的产权来界定权利,现在中国就是要改为这种情况。

  但中间还有一种,就是以管制来界定权利。界定什么权利?界定贪污的权利!这就是印度的情况。在印度,你管手表的进口,我管某种外汇管制,他管生产手袋的审批,各有所管。有管制,就有贪污。你贪污手表,我贪污手袋。这种权利界定得很清楚。贪污权还可以自由买卖,还可以继承,写进遗嘱里面。

  海关的贪污权也界定得很清楚。你星期一、三、五贪污,我星期二、四、六贪污(笑声),界定得非常清楚的。现在海关贪污权界定得很清楚,比如说走私的权利就界定得越来越清楚。你不相信的话,我可以拿一张价目表出来给你看,走私有这几种,你要我担保安全性有多高?绝对安全的是一个价。各种价格全都有,非常清楚。如果用管制来界定贪污权利的情况制度化了,那就无药可救。看看印度,无药可救嘛!(笑声)

  中国的问题是,上面要管,可市场是自下而上的,管制从上面来,又要讲市场,所以中间就撞得一塌糊涂。所以中国渐进的话,印度这一关就很难过。你要一步跨过去,所以我就说一定要快,一定要一整套的改革推出。弗里德曼提出一个"砍老鼠尾巴"的比喻。他说砍老鼠的尾巴要一刀砍下去,不要一寸一寸地砍,长痛不如短痛嘛!(笑声)弗里德曼经常说这个比喻。1993年我带他去见一位中国的省长。省长说,教授啊,我们中国的老鼠是很多条尾巴缠在一起的,先砍哪一条呢?(掌声)弗里德曼哑口无言(笑声)。我当然知道答案了,很明显嘛,所有尾巴一刀全砍掉不就行了嘛!(掌声)

  如果政策不是配套地一起推出来的话,麻烦就很大。哪样先做哪样后做,很难决定,很容易出错。弗里德曼一向主张放开价格管制,1988年我们向中国的领导人极力推荐这一点,结果一团糟。1991年,科斯拿诺贝尔奖,那次是诺贝尔奖90周年庆典,请我代表科斯发表演讲。我碰见弗里德曼,我跟他坐下来喝咖啡。我说,弗里德曼,我们建议中国取消价格管制,错了!他说,怎么会错啊?

  我说,那些国企解除价格管制,价格就会上升,但生产并不一定就会跟着上升,这就麻烦了。工人的工资不够买生活必需品,因为物价涨了,但生产没有增加。假如是企业的产权清晰,价格一上升,它的生产也会马上跟着增加,大家都获得好处嘛。但国企就不行了,因为国企是不管赚不赚钱的嘛,哪管你价格升不升?所以应该将国企产权明晰与放开价格管制一起进行。弗里德曼同意了。

  (3)当今中国最重要的三个问题

  首要的问题是特权阶层维护的既得利益的问题。几个行业都给堵塞住了,一个就是金融。不开放金融,就不可能有金融中心。这么大的一个国家没有一个金融中心是天大的笑话。刚才我跟你们中山大学黄达人校长说,中国没有金融中心,不开放金融,怎么可能搞商学院?学生读的书,里面讲的制度啊,融资办法啊,都是外国的嘛。金融中心要搞,就要取消所有外汇管制,要允许外国银行进入,要让外国的经纪进来。但现在这些全都给特权控制住了。我看中美签定的世贸协定,看不到取消外汇管制,那怎么能行?

  第二个问题,要让农村的劳动力能够转入城市,已经转了很多,但远远不够。一个国家的农业人口比例太高是不可能富裕的。这很容易嘛,取消户口管制就行了。把土地给农民,界定他们的产权,允许他们把地卖了,拿着本钱到城里去碰碰运气,然后就完全不用再管,市场自然会搞掂。

  也不用担心治安问题,因为城市人口增加,收入也会增加,只要不贪污,治安一定能搞好。1868年,那时是日本的明治维新,突然之间那个5岁大的皇帝,听了宰相的劝说,在一纸法令上签了个名,日本的土地权可以自由转让,农民无事可干,大量涌入城市,政府完全没有准备,结果什么问题都没有。要知道,明治维新是日本经济大增长的时期。

  香港也是一个例子,解放后很多人跑到香港去,文革时候很多人跑到香港,香港一点问题也没有。还有深圳,20年来,深圳人口暴升10倍,有什么问题吗?一点问题都没有,政府千万不要管它(笑声、掌声)。

  第三个问题,要发挥中国最大的长处。最大的长处是什么?人力资源。中国人努力、勤劳、物美价廉(笑声)。脑力也厉害,好像在座各位的脑力就很厉害。怎么发挥这个长处?取消海关吧!随他自由进出口。中国人哪里需要政府来保护?我们跟老外竞争,政府为什么要绑着我们的手脚?保护我们就等于绑着我们的手脚,那叫我们怎么去竞争?我认为根本不需要保护,完全不需要。如果中国绝对开放,取消所有的进出口管制,与外国直接公平竞争,完全不需要什么世贸组织。中国人怎么可能输?不可能的!(长时间的掌声)

  (4)我起码有六七篇文章可以传世

  我对中国只是关心,无意改进社会。我知道自己不行,这是自知之明。假如领导人来问我的意见,我是乐意提意见的。至于他们接不接受,我是不紧张的。所以有什么会议之类,我从来都不参加。因为参加这些会议的经济学家都有他们的意图。很坦白地说,有些人自己买了很多物业,所以他给政府的建议就是要救物业。我绝对不会为了自己的利益而提意见。弗里德曼对世界的影响举足轻重,可他从来没有说过一句言不由衷的话。这是我很佩服他的地方。

  15年前,诺贝尔奖评委会的头头来找我,他叫我把我自己的论文思想写成一本书,言下之意是如果我这样做的话,获奖机会很大。我本来是准备写的,但你叫我写的话,我就不写!(笑声、掌声)正如粤语俗话所说"面子是别人给的,脸是自己丢的"

  有件事情我是感到很骄傲的,我可以肯定,我起码有六七篇文章,100年后还会有人读。没有一个诺贝尔奖的得主敢这么说的。(笑声、掌声)。

  关于企业的问题,我想了13年。我是研究计件工资合约的,因为科斯要退休,逼我写出来。我写的时候对科斯很客气,但我认为他是错的。我对艾智仁和德姆塞茨也很客气,因为他们那篇著名的文章错得就更离谱了。

  所以你看了我那篇文章,就知道他们是错的,我那篇文章是1983年发表的,名字是《公司的合约性质》。这是我写得比较好的文章,100年后还会有人看。企业的问题,那篇文章已经全部解释清楚了。我做研究是这样的,自己做过的,认为是满意的,交了出去,发表了,我就从来不再干预。就像我的"佃农理论",发表之后,几百篇文章批评我,也有赞扬我的,很多人要我回应,我从不回应(笑声)。

  关于企业的文章,一年有几百篇,你问我的话,我就会说,只有我那篇是对的(笑声、掌声)。我为什么这样肯定呢?因为我花了很多时间在工厂里,对于那些计件工资合约我了解得很详细,我是拿着事实来分析问题,我不是在数学上绕圈子。所以我知道我这篇文章一定是最对的。

  我日日夜夜地写,刚一写完,我就知道,这篇文章一定可以传世。(笑声)于是我仰天大笑!(笑声、长时间的掌声)

  (5)对中国年青经济学家及其方法的评论

  现在还有很多经济学者认为产权不重要,他们搞的是所谓生产函数,英文叫"Production Function"。你说Production Function能解释经济繁荣吗?产权就可以!为什么今天这么多学者认为产权是不重要的呢?我的答案很简单:许多经济学家是很蠢的嘛!(笑声、掌声)

  现在很多年青的经济学家,我看不到他们有什么架构。经济学的目的不是改造社会,也不是数学游戏,而是解释世界的现象。一定要先有一个现象,然后才去解释,你一定要先知道世界是怎么样的。我所有的论著,都是从一个现象入手的,都要先了解世界,然后用很基本的理论解释这个现象。

  可是现在的博奕论,我不知道它解释了什么,我真的不知道啊。那些小年青,像杨小凯这样的人才,搞什么超边际分析,超这超那,是对什么现象超出来啊?他们算是比较好的经济学家了。超来超去,完全不知道他们在讲什么,看来看去也不明白。

  我走的经济学的路子跟这些小年青的主要区别在于,我对世界的事情认识很多,他们是坐在象牙塔里,很多数学,很多博奕理论,没什么内容。你要解释世事你就要了解世事,最蠢的学者就是解释完全不存在的东西。他们解释的是从来没有发生过的事。

  我几十年一直坐在玉器、古董市场里,走来走去就是研究这个东西。我也做过生意,亏本的也试过,这样才知道外面在发生什么事情。我和科斯的观点比较相近,他也知道很多。你可以到美国石油公司问,在世界上正式的石油专家中,真的懂的,他们一定会告诉你,是张五常(笑声)。我做石油研究,花了6年时间,逐个部门,逐个油田(看),那些油是怎么出来的,我全都知道。

  像我的"佃农理论",就是要解释为什么台湾的农产品在管制下产量会增加。我写关于买戏票的文章,我是要解释为什么价格高的座位会先卖完。这全都有现象在那里。我写中国的婚姻,为什么女人会缠脚,为什么会有童养媳,这些都是现象。

  可现在,我看了一百篇文章,看完了连一个现象都不存在,这是什么?是数学吧?不是经济学啊!现在这个博奕论,已经搞了20年了,你告诉我吧,它解释了哪一个现象?给一个我吧,我只需要一个!(笑声、掌声)

  你说你要搞新理论,你要告诉我你的新理论能解释什么现象?你说的现象是不是事实?那些小年青,什么都没有,你问他能解释什么,他也不知道,因为他对这个世界不了解嘛。现在经济学家的数学,平均是博士数学家的水平,??说不上了,搞得很抽象。

  你说经济学是艺术,数学写得很工整,很有学术性,这也是一种游戏,可以发表,可以拿诺贝尔奖(笑声),但你能解释什么?你能解释人的行为,我就服你;解释不了,就是废物。



haohao   2004-11-02 19:55:13 阅读:1486  评论:0  引用:0
非常高兴,也同时觉的自己的东西可以在世界上的每一个角落找到了
特别高兴呀
haohao   2004-11-02 18:41:13 阅读:1551  评论:0  引用:0
public class test
{
String s="nihao";
}
haohao   2004-10-27 17:50:47 阅读:1475  评论:0  引用:0
第一行为 UNIX 系统使用;第二行是 Windows 系列系统的用法;第三、四行则为 URL 的使用范例。

$fp = fopen("/home/rasmus/file.txt", "r");
$fp = fopen("c:\\mydata\\info.txt", "r");
$fp = fopen("http://www.php.net/", "r");
$fp = fopen("ftp://user:password@my.com/", "w");
?> 

haohao   2004-08-25 20:53:18 阅读:1781  评论:0  引用:0
 

SELECT * FROM table WHERE ROWNUM>90 AND ROWNUM<100; 

SELECT * FROM table WHERE ROWNUM<101; minus SELECT * FROM table WHERE ROWNUM<91;
haohao   2004-08-01 22:10:50 阅读:1357  评论:0  引用:0
   在石家庄实习的那段时间就琢磨自己毕业要些什么样的论文,必定早死早投胎吗?
  过去总是想那些大的不切实际的题目,大的都有点让你害怕.比如说三农问题,教育问题,我看这些都不是我所能写的国家发展委员会那些高人都想不出个办法在我们这样政治化大于一切的国家谁又能解决呢?
  前几天在校门口,胖子那里吃饺子,他给我说他都可以给我们到学校做报告,我死活不相信,结果他还真说了自己对小店的经营之道.
  后来想了想,的确如此,我们在石家庄实习时那条街上有数十家小吃店,可是好象只有一家生意做的最好,这家店的客人老是排队等候,可是它的隔壁几家却没有生意可做,怪不得我爸老是说:做买卖的千家万家,挣了钱的是一家两家呢?
  看来这种小店还真的需要去琢磨一下了.
haohao   2004-07-31 23:39:10 阅读:1229  评论:0  引用:0


ResultSet 接口
ResultSet 接口提供对数据表的访问。ResultSet 对象通常是通过执行“语句”来生成的。 

ResultSet 始终有一个游标指向其当前数据行。最初,游标定位在第一行的前面。next() 方法将游标移至下一行。 

getXXX 方法会检索当前行的列值。可使用列的索引号或列的名称来检索这些值。通常,使用列索引将更为有效。列是从 1 开始编号的。 

java.sql 包 

公共接口 ResultSet 

表 102 列示 ResultSet 接口中 DB2 Everyplace 支持的字段。 


表 102. ResultSet 接口字段
字段类型  字段  
static int  CONCUR_READ_ONLY 该常量指示不能更新的 ResultSet 对象的并行性方式。 注意:DB2 Everyplace 不支持 CONCUR_UPDATABLE。如果在创建“语句”对象时对 ResultSet 对象的并行性方式指定 CONCUR_UPDATABLE,则 DB2 Everyplace JDBC 驱动程序将对产生“语句”对象的“连接”对象发出 SQLWarning 并使用 CONCUR_READ_ONLY 代替。  
static int  TYPE_FORWARD_ONLY 该常量指示其游标只能向前移动的 ResultSet 对象的类型。  
static int  TYPE_SCROLL_INSENSITIVE 该常量指示可滚动但通常对他人所作的更改不敏感的 ResultSet 对象的类型。注意:不要经常使用此类型的 ResultSet 对象,原因是它可能会影响性能。此类型使用 SQL_INSENSITIVE 作为 CLI 语句属性 SQL_ATTR_CURSOR_SENSITIVITY 的值。有关详细信息,参阅 CLI 函数 SQLSetStmtAttr 的文档。  
static int  TYPE_SCROLL_SENSITIVE 该常量指示可滚动且通常对他人所作的更改敏感的 ResultSet 对象的类型。注意:此类型使用 SQL_UNSPECIFIED 作为 CLI 语句属性 SQL_ATTR_CURSOR_SENSITIVITY 的值。有关详细信息,参阅 CLI 函数 SQLSetStmtAttr 的文档。  


表 103 列示 ResultSet 接口中 DB2 Everyplace 支持的方法。 


表 103. ResultSet 接口方法
方法返回值类型  方法  
boolean  absolute(int row) JDBC 2.0。将游标移至结果集中的给定行号。  
void  afterLast() JDBC 2.0。将游标移至结果集的末尾,正好在最后一行的后面。  
void  beforeFirst() JDBC 2.0。将游标移至结果集的前方,正好在第一行的前面。  
void  clearWarnings() 清除此 ResultSet 对象上报告的所有警告。  
void  close() 立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待对象自动关闭时才释放它们。  
int  findColumn(String columnName) 将给定 ResultSet 列名映射至其 ResultSet 列索引。  
boolean  first() JDBC 2.0。将游标移至结果集中的第一行。  
BigDecimal  getBigDecimal(int columnIndex) JDBC 2.0。以具有全部精度的 java.math.BigDecimal 对象形式获取当前行中某个列的值。Palm OS 的 DB2 Everyplace JDBC 驱动程序不支持此方法。  
BigDecimal  getBigDecimal(int columnIndex, int scale) 以 Java 编程语言中的 java.math.BigDecimal 对象形式获取此 ResultSet 对象当前行中指定列的值。Palm OS 的 DB2 Everyplace JDBC 驱动程序不支持此方法。不受支持。  
BigDecimal  getBigDecimal(String columnName) JDBC 2.0。以具有全部精度的 java.math.BigDecimal 对象形式获取当前行中某个列的值。Palm OS 的 DB2 Everyplace JDBC 驱动程序不支持此方法。  
BigDecimal  getBigDecimal(String columnName, int scale) 以 Java 编程语言中的 java.math.BigDecimal 对象形式获取此 ResultSet 对象当前行中指定列的值。Palm OS 的 DB2 Everyplace JDBC 驱动程序不支持此方法。不受支持。  
Blob  getBlob(int columnIndex) JDBC 2.0。获取此 ResultSet 对象的当前行中的 BLOB 值。  
Blob  getBlob(String columnName) JDBC 2.0。获取此 ResultSet 对象的当前行中的 BLOB 值。  
boolean  getBoolean(int columnIndex) 以 Java 布尔值形式获取当前行中某列的值。  
boolean  getBoolean(String columnName) 以 Java 布尔值形式获取当前行中某列的值。  
byte  getByte(int columnIndex) 以 Java 编程语言中的字节形式获取此 ResultSet 对象当前行中指定列的值。  
byte  getByte(String columnName) 以 Java 编程语言中的字节形式获取此 ResultSet 对象当前行中指定列的值。  
byte[]  getBytes(int columnIndex) 以 Java 编程语言中的字节数组形式获取此 ResultSet 对象当前行中指定列的值。  
byte[]  getBytes(String columnName) 以 Java 编程语言中的字节数组形式获取此 ResultSet 对象当前行中指定列的值。  
int  getConcurrency() JDBC 2.0。返回结果集的并行性方式。  
Date  getDate(int columnIndex) 以 Java 编程语言中的 java.sql.Date 对象形式获取此 ResultSet 对象当前行中指定列的值。  
Date  getDate(int columnIndex, Calendar cal) 以 Java 编程语言中的 java.sql.Date 对象形式返回此 ResultSet 对象的当前行中指定列的值。  
Date  getDate(String columnName) 以 Java 编程语言中的 java.sql.Date 对象形式获取此 ResultSet 对象的当前行中指定列的值。  
double  getDouble(int columnIndex) 以 Java 双精度形式获取当前行中某列的值。  
double  getDouble(String columnName) 以 Java 双精度形式获取当前行中某列的值。  
float  getFloat(int columnIndex) 以 Java 浮点形式获取当前行中某列的值。  
float  getFloat(String columnName) 以 Java 浮点形式获取当前行中某列的值。  
int  getInt(int columnIndex) 以 Java 编程语言中的整数形式获取此 ResultSet 对象当前行中指定列的值。  
int  getInt(String columnName) 以 Java 编程语言中的整数形式获取此 ResultSet 对象的当前行中指定列的值。  
long  getLong(int columnIndex) 以 Java 长整型形式获取当前行中某列的值。  
long  getLong(String columnName) 以 Java 长整型形式获取当前行中某列的值。  
ResultSetMetaData  getMetaData() 检索此 ResultSet 对象的列的数目、类型和属性。  
Object  getObject(int columnIndex) 以 Java 对象形式获取当前行中某列的值。  
Object  getObject(String columnName) 以 Java 对象形式获取当前行中某列的值。  
int  getRow() JDBC 2.0。检索当前行号。  
short  getShort(int columnIndex) 以 Java 编程语言中的 short 形式获取此 ResultSet 对象当前行中指定列的值。  
short  getShort(String columnName) 以 Java 编程语言中的 short 形式获取此 ResultSet 对象当前行中指定列的值。  
Statement  getStatement() JDBC 2.0。返回产生此 ResultSet 对象的“语句”。  
String  getString(int columnIndex) 以 Java 编程语言中的 String 形式获取此 ResultSet 对象当前行中指定列的值。  
String  getString(String columnName) 以 Java 编程语言中的 String 形式获取此 ResultSet 对象当前行中指定列的值。  
Time  getTime(int columnIndex) 以 Java 编程语言中的 java.sql.Time 对象形式获取此 ResultSet 对象的当前行中指定列的值。  
Time  getTime(String columnName) 以 Java 编程语言中的 java.sql.Date 对象形式获取此 ResultSet 对象的当前行中指定列的值。  
Timestamp  getTimestamp(String columnName) 以 Java 编程语言中的 java.sql.Timestamp 对象形式获取此 ResultSet 对象的当前行中指定列的值。  
Timestamp  getTimestamp(int columnIndex) 以 Java 编程语言中的 java.sql.Timestamp 对象形式获取此 ResultSet 对象的当前行中指定列的值。  
int  getType() JDBC 2.0。返回此结果集的类型。  
SQLWarning  getWarnings() 返回此 ResultSet 上的调用报告的首次警告。  
boolean  isAfterLast() JDBC 2.0。指示游标是否在结果集中的最后一行后面。  
boolean  isBeforeFirst() JDBC 2.0。指示游标是否在结果集中的第一行前面。  
boolean  isFirst() JDBC 2.0。指示游标是否在结果集中的第一行上。  
boolean  isLast() JDBC 2.0。指示游标是否在结果集中的最后一行上。对于具有类型 TYPE_FORWARD_ONLY 的结果集,不支持此方法。  
boolean  last() JDBC 2.0。将游标移至结果集中的最后一行。  
boolean  next() 将游标从当前位置向下移动一行。  
boolean  previous() JDBC 2.0。将游标移至结果集中的前一行。  
boolean  relative(int rows) JDBC 2.0。将游标移动相对行数,正数或负数。  
boolean  wasNull() 报告读取的最后一列是否具有值 SQL NULL。  


相关任务 

开发 DB2 Everyplace Java 应用程序 
相关参考 

DB2 Everyplace JDBC 支持的概述 
JDBC 报告的 SQLState 消息 
SQLSetStmtAttr - 设置与语句相关的选项 
haohao   2004-07-31 22:25:38 阅读:1561  评论:0  引用:0
dao技术 
使用JBoss和PostgreSQL-----快速开发EJB和J2EE Web Application  
hanqw3 原创  (参与分:20,专家分:30)   发表:2003-8-4 上午11:46   更新:2003-8-4 下午2:49   版本:2.0   阅读:4218次  
  


使用JBoss和PostgreSQL-----快速开发EJB和J2EE Web Application 


Developing J2EE Web Application on Jboss and PostgreSQL(chinese version) 


作者:Han QW, 转载请指明出处 如有不当之处,敬请指出 


先安装JSDK,再安装JBoss. 
安装JSDK,必须获得一套对应于用户的操作系统的JDK, 
我的安装的文件目录是 
WINDOWS2000:    d:\s1studio_jdk\j2sdk1.4.1 
linux:         /root/s1studio_jdk/j2sdk1.4.1 
为了用EJB, 需要一个j2ee-1.3.jar或者j2ee-1.2.jar, 
如果安装了Sun One Studio 或者 J2EE (www.sun.com )这个文件已经有. 
把这个文件放在classpath路径上. 
或者使用jboss-j2ee.jar, 安装JBoss后在$JBoss\client中可找到.  
建议安装Sun One Studio, 用Sun One Studio编译JAVA源程序,  
不用设置classpath, 省去不少过程. 

安装JBoss: 
把JBoss的压缩包解开,放在任一目录上, 
我的安装的文件目录是 
/dose/jboss-3.0.4_tomcat-4.1.12 (REDHAT8.0) 
E:\jboss-3.0.4_tomcat-4.1.12    (WINDOWS2000) 
 WINDOWS2000, linux共用同一套JBoss. 

配置JBoss: 
启动JBoss需要执行一个脚本文件: 
linux:run.sh 
WINDOWS对应的是:run.bat 

(1) 
在JBoss\bin\run.bat (for Windows)开头插入一行 
set JAVA_HOME = d:\s1studio_jdk\j2sdk1.4.1 
在JBoss\bin\run.sh (for Linux)开头插入一行 
JAVA_HOME="/root/s1studio_jdk/j2sdk1.4.1" 

或者 
(2)设置系统环境变量JAVA_HOME,指向JDK 

运行JBoss, run.sh或者run.bat  
当看到启动JBoss的信息时,说明启动了. 
服务器简单的测试: 
JBoss默认的WEB端口为8080,我们可以在打开一个浏览器输入地址 
http://localhost:8080/jmx-console 
当在浏览器看到JBoss的信息时,说明安装配置JBoss成功了. 



建立下面的目录和文件(注意大小写). 

FIRST.EAR 

|-----META-INF (application.xml) 

|-----First.jar 
|        |-----META-INF (ejb-jar.xml,jboss.xml) 
|        `-----Dev 
|               |-----First(FirstSession.java, FirstSessionHome.java, FirstSessionBean.java) 
|               |-----Delegate(NewDelegate.java) 
|               `-----Dao(MysqlDao.java) 

`-----First.war(index.jsp) 
        | 
        `-----WEB-INF (jboss-web.xml, web.xml) 
                |-----classes 
                `-----lib 

/* 
** 
**MysqlDao.java  
** 
*/ 
package Dev.Dao; 

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

import javax.naming.InitialContext; 
import javax.sql.DataSource; 


public class MysqlDao { 

    public Connection getConnection() throws Exception { 

        InitialContext ctx = new InitialContext(); 

        DataSource ds = (DataSource) ctx.lookup("java:/PostgresDS"); 


        Connection conn = null; 
        Statement stmt = null; 

        try { 
            conn = ds.getConnection(); 

        } catch (SQLException sqlEx) { 
            System.out.println("Error connect to pool."); 
        } 

        return conn; 
    } 

    public String getName(String id) throws Exception { 

        Connection conn = null; 
        Statement stmt = null; 
        ResultSet rs = null; 
        String name = ""; 

        try { 
            conn = getConnection(); 
            if ( conn !=null )System.out.println("Get conecttion. "+ conn.toString()); 
            stmt = conn.createStatement(); 
            if ( stmt !=null )System.out.println("Get Statement. "+ stmt.toString()); 
            String sql = "SELECT * from users where id = '"+id+"'"; 
            System.out.println("Sql from getId(): "+sql); 
           rs = stmt.executeQuery(sql); 
            if ( rs !=null )System.out.println("Get result. "); 
           if (rs.next()){ 
            name = rs.getString("name"); 
               } 

        } catch (Exception sqlEx) { 
        System.out.println("Error from getName()."); 
                System.out.println("Error from DAO.getName() :" + sqlEx.getMessage()); 
        }finally { 
            if (conn != null) { 
               try { conn.close(); } catch (Exception sqlEx) { } 
            } 
        } 
        return name; 
    } 

    public String getCountry(String id) throws Exception { 

        Connection conn = null; 
        Statement stmt = null; 
        String name = ""; 

        try { 
            conn = getConnection(); 
            stmt = conn.createStatement(); 
            String sql = "SELECT * from users where id = '"+id+"'"; 
            System.out.println("Sql from getCountry(): "+sql); 
               java.sql.ResultSet rs = stmt.executeQuery(sql); 
               if (rs.next()) 
            { 
                   name = rs.getString("Country"); 
              } 

        } catch (SQLException sqlEx) { 
            System.out.println("Error from getCountry()."); 
        }finally { 
            if (conn != null) { 
               try { conn.close(); } catch (Exception sqlEx) { } 
            } 
        } 
        return name; 
    } 




/* 
** 
**NewDelegate.java  
** 
*/ 
package Dev.Delegate; 

import java.lang.*; 
import Dev.First.*; 


public class NewDelegate { 

    Dev.First.FirstSession bean = null; 
     
    public NewDelegate( ){ 
       try { 
       javax.naming.InitialContext ctx = new javax.naming.InitialContext(); 
       Object objref = ctx.lookup("ejb/FirstSession"); 
       Dev.First.FirstSessionHome testBean = (Dev.First.FirstSessionHome) 
          javax.rmi.PortableRemoteObject.narrow 
          (objref,Dev.First.FirstSessionHome.class); 
       bean = testBean.create(); 
       System.out.println("From JSP"); 
    } catch (Exception NamingException) { 
           NamingException.printStackTrace(); 
    } 
    } 
   
    public String Welcome() { 
    String msg = ""; 
    try { 
            msg = bean.Welcome(); 
    } catch (Exception NamingException) {  
           NamingException.printStackTrace(); 
         } 
           return msg; 
    } 
     
    public String getName(String id) { 
    String name = ""; 
    try { 
            name = bean.getName(id); 
    } catch (Exception NamingException) { NamingException.printStackTrace();} 
        return name; 
    }  
     
    public String getCountry(String id) { 
    String country = ""; 
    try { 
             country = bean.getCountry(id); 
    } catch (Exception NamingException) { NamingException.printStackTrace();} 
        return country; 
    }         


/* 
** 
**FirstSession.java  
** 
*/ 
package Dev.First; 

import java.lang.*; 
import java.rmi.RemoteException; 
import javax.ejb.CreateException; 
import javax.ejb.EJBException; 
import javax.ejb.SessionBean; 
import javax.ejb.SessionContext; 


public interface FirstSession extends javax.ejb.EJBObject{ 

         public String Welcome() throws java.rmi.RemoteException; 
          
         public String getName(String id) throws java.rmi.RemoteException; 
          
         public String getCountry(String id) throws java.rmi.RemoteException; 




/* 
** 
**FirstSessionHome.java  
** 
*/ 
package Dev.First; 

import java.lang.*; 
import java.rmi.RemoteException; 
import javax.ejb.CreateException; 
import javax.ejb.EJBException; 
import javax.ejb.SessionBean; 
import javax.ejb.SessionContext; 


public interface FirstSessionHome extends javax.ejb.EJBHome{ 

public FirstSession create() throws javax.ejb.CreateException, java.rmi.RemoteException; 




/* 
** 
**FirstSessionBean.java  
** 
*/ 
package Dev.First; 

import java.rmi.RemoteException; 
import javax.ejb.CreateException; 
import javax.ejb.EJBException; 
import javax.ejb.SessionBean; 
import javax.ejb.SessionContext; 


public class FirstSessionBean implements SessionBean{ 

public void ejbCreate() throws CreateException { 



public String Welcome(){ 
      String msg="Hello! This My Session Bean From Jboss."; 
      System.out.println(msg); 
      return msg; 


public String getName(String id){ 
      String name = ""; 
      System.out.println("From bean before getName :"+ name); 
      try{ 
      Dev.Dao.MysqlDao dao = new Dev.Dao.MysqlDao(); 
      name = dao.getName(id); 
      System.out.println("From bean after getName :"+ name); 
      }catch(Exception e){ System.out.println(e.getMessage());} 
      return name; 


public String getCountry(String id){ 
      String country = ""; 
      try{       
      Dev.Dao.MysqlDao dao = new Dev.Dao.MysqlDao(); 
      country = dao.getCountry(id); 
      }catch(Exception e){ }       
      return country; 


public void setSessionContext( SessionContext aContext ) throws EJBException { 



public void ejbActivate() throws EJBException { 



public void ejbPassivate() throws EJBException { 



public void ejbRemove() throws EJBException { 








/*Don't put the following lines into index.jsp 
** 
**index.jsp  
** 
*/Don't put the above lines into index.jsp 

<%@page language="java" %> 

<% 

    String msg = ""; 
    String msg1 = ""; 
    Dev.Delegate.NewDelegate nn = new Dev.Delegate.NewDelegate(); 
    if (request.getParameter("id") != null &&  
           request.getParameter("id") != ""&&  
           !request.getParameter("id").equals("")){ 
        String id = request.getParameter("id"); 
        String name = ""; 
        Dev.Dao.MysqlDao dao = new Dev.Dao.MysqlDao(); 
        name = nn.getName(id);      //access database through session bean 
        //name = dao.getName(id);   //access database directly 
        if(name!= null && !name.equals("")){ 
            msg1 ="Welcome  " + name +" !     You are from  "+ dao.getCountry(id)+ " ."; 
        }else{ 
            msg1 ="Please Check Your ID. : " + id; 
        } 

    } 
    msg = nn.Welcome() ; 
%> 
 

 
Welcome 
 

 

 <%= msg %> 
 

 

Your ID: 

 


 
 

 

 

<%=(msg1 == "")? "":msg1 + "
 
 
Connect to Database OK." %> 

 
 



不要将此以上5行存入文件, 下同. 
 
"http://java.sun.com/dtd/ejb-jar_2_0.dtd"> 

 

 First 
 First 

 

 
 
     My First Session Bean 
     FirstSession 
     Dev.First.FirstSessionHome 
     Dev.First.FirstSession 
     Dev.First.FirstSessionBean 
     Stateless 
     Container 
 

 

 

 

 




 
 
 

 

 

 
FirstSession 
ejb/FirstSession 
 

 

 
 

 



 
 
"http://www.jboss.org/j2ee/dtd/jboss-web.dtd"> 

 


     
        jdbc/PostgresDS 
        javax.sql.DataSource 
        java:/PostgresDS 
    
 

 



 
 

"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> 

 

 
  Postgresql driver 
  jdbc/PostgresDS 
  javax.sql.DataSource 
  Container 
 

 




 
 

 
First 
 
 
First.war 
/First 
 
 

 
First.jar 
 
 



编译JAVA源程序,生成class文件. 
进入JAVA源程序目录, 运行:  
javac -classpath  %classpath%;%jboss%\server\default\deploy\First.ear\First.jar *.java 
或者 
javac -classpath  %jboss%\server\default\deploy\First.ear\First.jar;%jboss%\client\jboss-j2ee.jar *.java 

Copy 目录First.ear to jboss\server\default\deploy. 
打开浏览器输入地址 http://localhost:8080/First 

到此, 在浏览器看到:  Hello! This My Session Bean From Jboss.  
说明这个EJB工作了. 

如果按按钮, 没反应或出错. 原因没安装配置数据库, 下面安装配置Postgres数据库 


For Windows2000 
下载 PgSQL731wina1.exe (http://www.postgresql.org), 
Finally you will see the next line, you need enter the password for Administrator 
最后你将看下一个行,你必须为用户Administrator输入password.  
******************** 
Enter password of user `.\Administrator':123456 
******************** 

记下此password, 我的口令是123456. 

从开始菜单 > Programm > PostgresSQL > Adjust PostgresSQL Configuration file 
它将在Wordpad中打开PostgresSQL Configuration文件, 找到下列行, 



#    Connection Parameters 

#tcpip_socket = false 
#ssl = false 

#max_connections = 32 
#superuser_reserved_connections = 2 

#port = 5432  

修改编辑: 

#    Connection Parameters 

tcpip_socket = true 
#ssl = false 

#max_connections = 32 
#superuser_reserved_connections = 2 

port = 5432  

接着,保存文件. 

起动PostgresSQL服务器: 
开始菜单>Programm>PostgresSQL>Utilies>Start PostgresSQL server 
起动命令行: 
开始菜单>Programm>PostgresSQL>Utilies>Command Shell 


执行下列命令,准备数据, 
Administrator@SAN / 
$ dir 

$ cd bin 

$ createdb test 

$ psql test 

test=# create table users 
test-# (name varchar(20), 
test(# id varchar(20), 
test(# country varchar(20)); 
test=# insert into users values ('Sam', '123', 'China'); 
test=# insert into users values ('Tom', '321', 'USA'); 
test=# insert into users values ('Sean', '231', 'France'); 

test=# select * from users; 
 name | id  | country 
------+-----+--------- 
 Sam  | 123 | China 
 Tom  | 321 | USA 
 Sean | 231 | France 
(3 rows) 

test=# 

到此, 数据准备就绪. 



For RedHat: 
以root登陆, 执行下列命令,准备数据, 
  
mkdir /usr/local/pgsql/data 
chown postgres /usr/local/pgsql/data 
su - postgres 
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data 

Open and edit /usr/local/pgsql/data/pg_hba.conf 

local      all                                          trust 
host       all         127.0.0.1     255.255.255.255    trust 

just delete #, and save. 


[root@localhost root]# su - postgres 
-bash-2.05b$ /usr/bin/postmaster -i -D /usr/local/pgsql/data >logfile 2>&1 & 
-bash-2.05b$ /usr/bin/createdb test 
-bash-2.05b$ /usr/local/pgsql/bin/psql test 
test=#    .......the following same as Windows2000 

到此, 数据准备就绪. 


执行shutdown.bat or shutdown.sh, 停止Jboss Server. 

找到JDBC drive. 
为了在Jboss中使用连接池,需要拷贝jdbc drive 到Jboss/server/default/deploy ,  在linux 我们能找到/usr/share/pgsql/pgjdbc2.jar,在wondows2000,我们能找到PostgreSQL\usr\share\postgresql\java\postgresql.jar 
把其中之一复制到Jboss/server/default/deploy 


配置Jboss 

(1) 复制 $Jboss/examples/jca/postgres-service.xml 到 $Jboss/server/default/deploy/ 

(2) 打开编辑Jboss/server/default/deploy/postgres-service.xml 

        PostgresDS 
         
           
            jdbc:postgresql://localhost/test 
            org.postgresql.Driver 
             
            Administrator 
            123456 
          
 

In my example, set Username  Administrator, password  123456 for windows 2000 
        set Username  Postgres, no password  for Linux. 
在我的例子中, 
windows2000,   用户:Administrator,password:123456 
Linux(RH8.0),  用户:Postgres, 没有password 
因为PostgresSQL和windows2000使用不同的default用户名,所以在linux和window2000中这文件不同.当然,你可以加相同的PostgresSQL用户名和password在linux和window2000中, 这样这文件就相同了. 

保存文件. 

(3) 打开编辑 $Jboss/server/default/conf/standardjbosscmp-jdbc.xml 
找到: 
      java:/DefaultDS 
      Hypersonic SQL 
加入: 
      java:/PostgresDS 
      Postgres  
保存文件. 

(4) open and edit $Jboss/server/default/conf/standardjaws.xml 
找到: 
   java:/DefaultDS 
   Hypersonic SQL 
   false 
加入: 
   java:/PostgresDS 
   Postgres 
   false  
  
  

------
 
回复此文章 | edit  | hide  
回复主题:Re:dao技术 | 作者: haohao | 军衔:六级军士 | 发表时间:2004-07-27 10:20:33 
=============Student.java==========  
import java.sql.*;  
public class Student implements java.io.Serializable{  
private String id;  
private String name;  
private Date birthday;  

public Student(){}  
public Student(String id, String name, Date birthday){  
this.id = id;  
this.name = name;  
this.birthday = birthday;  
}  

public String getId() { return id; }  
public void setId(String id) { this.id = id; }  

public String getName() { return name; }  
public void setName(String name) { this.name = name; }  

public Date getBirthday() { return birthday; }  
public void setBirthday(Date birthday) { this.birthday = birthday; }  
}  

=================Course.java======================  
public class Course implements java.io.Serializable{  
private String id;  
private String name;  
private String description;  

public Course() {}  
public Course(String id, String name, String description){  
this.id = id;  
this.name = name;  
this.description = description;  
}  

public String getId() { return id; }  
public void setId(String id) { this.id = id; }  

public String getName() { return name; }  
public void setName(String name ) { this.name = name; }  

public String getDescription() { return description; }  
public void setDescription(String description) { this.description = description; }  
}  

==============SMdao.java==================  
import java.sql.*;  
public interface SMdao {  
public Student createStudent(String id, String name, Date birthday);  
publc Course createCourse(String id, String name, String description);  

public Student findStudent(String id);  
public Course findCourse(String id);  

public void clean();  
}  

==============FileSMdaoImpl.java==============  
import java.util.Properties;  
import java.sql.*;  
import java.io.*;  

public class FileSMdaoImpl implements SMdao {  
private Properties pro;  
private final static String SFILE_URL = "student.file.url";  
private final static String CFILE_URL = "course.file.url";  
public FileSMdaoImpl(Properties pro){  
this.pro = pro;  
}  

public Student createStudent(String id, String name, Date birthday) {  
FileOutputStream fos = null;  
ObjectOutputStream oos = null;  
Student stu = null;  

try {  
fos = new FileOutputStream(pro.getProperty(FILE_URL), true);  
oos = new ObjectOutputStream(fos);  
stu = new Student(id, name, birthday);  
oos.writeObject(stu);  
} catch(Exception e) { stu = null; }  
finally{  
try { if(oos != null) oos.close(); } catch(Exception e){}  
try { if(fos != null) oos.close(); } catch(Exception e) {}  
}  

return stu;  
}  

public Course createCourse(String id, String name, String description){  
return null;  
}  

public Student findStudent(String id) {  
return null;  
}  

public Course findCourse(String id) {  
return null;  
}  

public void clean() {}  
}  
==============DBSMdaoImpl.java==============  
import java.sql.*;  
import java.util.Properties;  

public class DBSMdaoImpl implements SMDao {  
private Connection con;  
private final static String DBDRV = "db.driver";  
private final static String DBURL = "db.url";  
private final static String DBUSER = "db.user";  
private final static String DBPASSWD = "db.password";  

public DBSMdaoImpl(Properties pro) {  
try {  
Class.forName(pro.getProperty(DBDRV));  
String user = pro.getProperty(DBUSER);  
String passwd = pro.getProperty(DBPASSWD);  
if(user != null)  
con = DriverManager.getConnection(pro.getProperty(DBURL),  
user, passwd);  
else  
con = DriverManager.getConnection(pro.getProperty(DBURL));  
} catch(Exception e){}  
}  

public Student createStudent(String id, String name, Date birtyday) {  
if(con == null) return null;  
Student stu = null;  
PreparedStatement stm = null;  

try {  
stm = con.prepareStatement("insert into student(id, name, birthday) " +  
                                                            "values(?, ?, ?)");  
stm.setString(1, id);  
stm.setString(2, name);  
stm.setDate(3, birthday);  

if(stm.executeUpdate() > 0)  
stu = new Student(id, name, birthday);  
}catch(Exception e){}  
finally{  
try {if(stm != null) stm.close();}  
catch(Exception e) {}  
}  

return stu;  
}  

public Course createCourse(String id, String name, String desc) { return null; }  
public Student findStudent(String id) { return null; }  
public Course findCourse(String id) { return null; }  

public void clean() {  
try {  
if(con != null) con.close();  
}catch(Exception e) {}  
}  
}  

===============SMdaoFactory.java===============  
import java.util.*;  

public class SMdaoFactory {  
Properties pro;  
public static final String TYPE_FILE = "file";  
public static final String TYPE_DB = "database";  
private String type;  
      private static SMdaoFactory factory;  
    static{  factory = new SMdaoFactory();}  

private SMdaoFactory() {  

}  

public static SMdaoFactory newInstance() { return factory; }  

public void setType(String type) { this.type = type; }  

public void setProperties(Properties pro) { this.pro = pro; }  

public SMdao createSMdao() {  
if(type.equals(TYPE_FILE))  
return new FileSMdaoImpl(pro);  
else  
return new DBSMdaoImpl(pro);  
}  
}  


=================Main.java=========================================  
import java.io.*;  
import java.util.*;  
import java.sql.*;  
public class Main{  
public static void main(String args[]){  
Properties pro = new Properites();  
try {  
pro.load(Main.class.getResourceAsStream("conf.properties");  
}catch(Exception e) {  
e.printStackTrace();  
System.exit(1);  
}  

SMdaoFactory factory = SMdaoFactory.newInstance();  
factory.setType(SMdaoFactory.TYPE_DB);  
factory.setProperties(pro);  
SMdao dao = factory.createSMdao();  
GregorainCalendar calendar = new GregorainCalendar();  
calendar.set(Calendar.YEAR, 1975);  
calendar.set(Calendar.MONTH, 2);  
calendar.set(Calendar.DAY_OF_MONTH, 21);  
java.sql.Date birthday = new java.sql.Date(calendar.getTimeInMills());  
Student stu = dao.createStudent("12345", "George", birthday);  
}  
}  
==============conf.properties===================  
db.driver=COM.pointbase.jdbc.jdbcUniversalDriver  
db.url=jdbc:pointbase:server://george/sample  
db.user=pbpulic  
db.password=pbpublic  

student.file.url=student  
course.file.url=course 
------
 
回复此文章 | edit  | hide  
回复主题:Re:Re:dao技术 | 作者: haohao | 军衔:六级军士 | 发表时间:2004-07-27 10:23:32 
http://www.matrix.org.cn/article/853.html 
   
  
   免费注册  
 用户登陆  
 帮助中心  
  
  
JAVA首页 Matrix动态 Java专栏 Java下载 Java网站 用户中心 开源项目 JAVA论坛  
  
  
您现在位于: 首页 → Java专栏---浏览技术文章   
读《J2EE核心模式》(DAO模式)  
2004年4月7日  作者:martin  Matrix-与Java共舞      
  
    
   
 读《J2EE核心模式》(DAO模式) 
from Martin的blog: http://www.matrix.org.cn/blog/martin/ 

很多的J2EE应用程序需要使用持久性数据(数据库、文件等)。不同的程序,持久性存储是各不相同的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。如果应用程序要在不同的持久性存储间迁移,这些访问特定持久存储层的代码将面临重写。 

如何解决这个问题?且看"DAO模式" 

数据访问对象(Data Acess Object) 模式 


一.环境 
根据数据源不同,数据访问也不同。根据存储的类型(关系数据库、面向对象数据库、文件等等)和供应商实现不同,持久性存储(比如数据库)的访问差别也很大。 

二.问题 
许多真是的J2EE应用程序需要在一定程度上使用持久性数据。对于许多应用程序,持久性存储是使用不同的机制实现的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。 
比如,应用程序使用实体bean(这里应该是指BMP的bean,CMP的bean已大大降低了与RDBMS的耦合)的分布式组件来表示持久性数据,或者使用JDBC API来访问驻留在某关系数据库管理系统(RDBMS)中的数据,这些组件中包含连接性性和数据访问代码会引入这些组件与数据源实现之间的紧密耦合。组件中这类代码依赖性使应用程序从某种数据源迁移到其他种类的数据源将变得非常麻烦和困难。当数据源变化时,组件也需要改变,以便于能够处理新类型的数据源。 

(举个例子来说,我们UPTEL系统是使用JDBC API对 ORACLE数据库进行连接和数据访问的,这些JDBC API与SQL语句散布在系统中,当我们需要将UPTEL迁移到其他RDBMS时,比如曾经迁移到INFORMIX,就面临重写数据库连接和访问数据的模块。) 

三.作用力 
1.诸如bean管理的实体bean、会话bean、servlet等组件往往需要从持久性存储数据源中检索数据,以及进行数据存储等操作。 
2.根据产品供应商的不同,持久性存储API差别也很大,这些API和其能力同样根据存储的类型不同也有差别,这样存在以下缺点,即访问这些独立系统的API很不统一。 
3.组件需要透明于实际的持久性存储或者数据源实现,以便于提供到不同供应商产品、不同存储类型和不同数据源类型的更容易的移植性。 

四.解决方案 
使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便检索和存储数据。 
DAO实现了用来操作数据源的访问机制。数据源可以时RDBMS,LDAP,File等。依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时,DAO向客户端提供的接口不会变化,所有该模式允许DAO调整到不同的存储模式,而不会影响其客户端或者业务组件。重要的是,DAO充当组件和数据源之间的适配器。 

(按照这个理论,如果我们UPTEL系统使用了DAO模式,就可以无缝的从ORACLE迁移到任何一个RDBMS了。梦想总是很完美的,且看看DAO模式如何实现) 

1.结构,图1是表示DAO模式中各种关系的类图。 

此主题相关图片如下: 


2.参与者和职责 
1)BusinessObject(业务对象) 
代表数据客户端。正是该对象需要访问数据源以获取和存储数据。 
2)DataAccessObject(数据访问对象) 
是该模式的主要对象。DataAccessObject抽取该BusinessObject的低层数据访问实现,以保证对数据源的透明访问。BusinessObject也可以把数据加载和存储操作委托给DataAccessObject。 
3)DataSource(数据源) 
代表数据源实现。数据源可以是各RDBMSR数据库,OODBMS,XML文件等等。 
4)valueObject(值对象) 
代表用做数据携带着的值对象。DataAccessObject可以使用值对象来把数据返回给客户端。 
DataAccessObject也许会接受来自于客户端的数据,其中这些用于更新数据源的数据存放于值对象中来传递。 

3.策略 
1).自动DAO代码产生策略 
因为每个BusinessObject对应于一个特殊的DAO,因此有可能建立BusinessObject,DAO和低层实现(比如RDBMS中的表)之间的关系(映射)。一点这些关系(映射)已经建立,我们就可以编写与应用程序有馆的代码生成的简单工具了(什么?自己写GP程序?用ORM的附带工具自动生成不就完了,最多自己写几个Adapter,牛人就是不同,啥都要自己写...),其中的工具可以产生该应用程序需要的所有DAO代码。 
如果DAO需求很复杂,我们可以采用第三方工具,其中这些工具提供对象到RDBMS数据库的关系映射(这里指的是前面提到的ORM工具,全称是Object Relation Mapping,目前成熟的ORM工具有很多:Hibernate,OJB,Torque,TopLink等等)。 
这些工具通常包含GUI工具来把业务对象映射到持久性存储对象,并且因而定义中间DAO。一旦这些映射完成,这些工具会自动地生成代码,并且也许会提供其他增值功能,比如结果缓冲、查询缓冲、与应用程序集成,以及与其他第三方产品(比如分布式缓冲)地继承,等等。 
(增值服务:Torque提供了结果缓冲,Hibernate提供了对Oracle数据库SQL指令的优化,OJB提供JDO API、OMDB API) 

2).数据访问对象的工厂策略 
通过调整抽象工厂和工厂方法模式,DAO模式可以达到很高的灵活度。 
当低层存储不会随着实现变化而变化时,该策略可以使用工厂方法模式来实现该策略。以产生应用程序需要的大量DAO。图2是这种情况下的类图。 

此主题相关图片如下: 



当低层存储随着实现变化而变化时,该策略可以使用抽象工厂方法模式而实现。 
图3是这种情况下的类图。 

此主题相关图片如下: 



5.结果 
1).启用透明性 
业务对象可以是使用数据源,而无须了解该数据源实现的具体细节。访问是透明的,原因是实现被隐藏在DAO的内部。 
2).启用更容易的迁移 
DAO层使应用程序更加容易地迁移到一个不同的数据库实现。业务对象不了解低层数据实现。因而,该迁移只涉及对DAO层的变化。更进一步说,如果使用工厂策略,则有可能为每一个低层存储实现提供一个具体工厂实现。在这种情况下,迁移到不同的迁移实现意味着给应用程序提供一个新的工厂实现。 
3).减少业务对象中代码复杂度 
由于DAO管理所有的数据访问复杂性,它可以简化业务对象和其他使用DAO的客户端中的代码。所有与实现有关的代码(比如sql语句)都被包含在DAO中,而不是包含在业务对象中。这样做提高了代码的可读性,已经代码生产效率。 
4).把所有的数据访问集中到一个独立的层。 
因为所有的数据访问操作现在被委托给DAO,所有单独的数据访问层可以被看作把数据访问实现与应用程序中的其他代码相隔离的。这种集中化使应用程序更容易地维护和管理。 
5).不适用于容器管理的持久性 
由于EJB容器用容器管理的持久性(CMP)来管理实体bean,该容器会自动地服务所有的持久性存储访问。使用容器管理的实体bean的应用程序不需要DAO层,因为该应用程序服务器透明地提供该功能。然而,当需要组合使用CMP和BMP时,DAO仍旧有用处。 
6).添加其他层 
DAO会在数据客户端和数据源之间创建其他的对象层,其中该数据源需要被设计和实现以便于权衡该模式的好处。但是选择本方法也会带来额外的开销。 
7).需要类层次设计 
在使用工厂策略时,我们需要设计和实现具体工厂的层次,以及这些工厂产生的具体产品层次。如果能够确保这种灵活性,则有必要考虑这种额外的工作。这样做会增加设计的复杂性。然而,在实现该工厂策略时,你可以首先考虑工厂方法模式,然后再根据需要过渡到抽象工厂。 

六.范例代码 
1.实现数据访问对象模式 
范例9-4时表示Customer信息的持久性对象的DAO范例代码。当findCustomer()被调用时,CloudscapeCustomerDAO创建一个Customer值对象。 
范例9-6是使用DAO的范例代码。 

2.实现数据访问对象的工厂策略 
1)使用工厂方法模式 
2)使用抽象工厂模式 
范例代码9-2是CloudscapeDAOFactory的范例代码。 
范例代码9-3中的CustomerDAO接口为Customer持久性对象定义了DAO方法,这些接口是被所有具体DAO实现来实现的,比如CloudscapeCustomerDAO、OracleCustomerDAO、已经SybaseCustomerDAO。Account和OrederDAO接口也与此类似。  


Example 9.1 Abstract DAOFactory Class 

// Abstract class DAO Factory 
public abstract class DAOFactory { 

// List of DAO types supported by the factory 
public static final int CLOUDSCAPE = 1; 
public static final int ORACLE = 2; 
public static final int SYBASE = 3; 
... 

// There will be a method for each DAO that can be  
// created. The concrete factories will have to  
// implement these methods. 
public abstract CustomerDAO getCustomerDAO(); 
public abstract AccountDAO getAccountDAO(); 
public abstract OrderDAO getOrderDAO(); 
... 

public static DAOFactory getDAOFactory( 
int whichFactory) { 

switch (whichFactory) { 
case CLOUDSCAPE:  
return new CloudscapeDAOFactory(); 
case ORACLE :  
return new OracleDAOFactory();  
case SYBASE :  
return new SybaseDAOFactory(); 
... 
default :  
return null; 





Example 9.2 Concrete DAOFactory Implementation for Cloudscape 

// Cloudscape concrete DAO Factory implementation 
import java.sql.*; 

public class CloudscapeDAOFactory extends DAOFactory { 
public static final String DRIVER= 
"COM.cloudscape.core.RmiJdbcDriver"; 
public static final String DBURL= 
"jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB"; 

// method to create Cloudscape connections 
public static Connection createConnection() { 
// Use DRIVER and DBURL to create a connection 
// Recommend connection pool implementation/usage 

public CustomerDAO getCustomerDAO() { 
// CloudscapeCustomerDAO implements CustomerDAO 
return new CloudscapeCustomerDAO(); 

public AccountDAO getAccountDAO() { 
// CloudscapeAccountDAO implements AccountDAO 
return new CloudscapeAccountDAO(); 

public OrderDAO getOrderDAO() { 
// CloudscapeOrderDAO implements OrderDAO 
return new CloudscapeOrderDAO(); 

... 



Example 9.3 Base DAO Interface for Customer 

// Interface that all CustomerDAOs must support 
public interface CustomerDAO { 
public int insertCustomer(...); 
public boolean deleteCustomer(...); 
public Customer findCustomer(...); 
public boolean updateCustomer(...); 
public RowSet selectCustomersRS(...); 
public Collection selectCustomersVO(...); 
... 



Example 9.4 Cloudscape DAO Implementation for Customer 

// CloudscapeCustomerDAO implementation of the  
// CustomerDAO interface. This class can contain all 
// Cloudscape specific code and SQL statements.  
// The client is thus shielded from knowing  
// these implementation details. 

import java.sql.*; 

public class CloudscapeCustomerDAO implements  
CustomerDAO { 

public CloudscapeCustomerDAO() { 
// initialization  


// The following methods can use 
// CloudscapeDAOFactory.createConnection()  
// to get a connection as required 

public int insertCustomer(...) { 
// Implement insert customer here. 
// Return newly created customer number 
// or a -1 on error 


public boolean deleteCustomer(...) { 
// Implement delete customer here 
// Return true on success, false on failure 


public Customer findCustomer(...) { 
// Implement find a customer here using supplied 
// argument values as search criteria 
// Return a value object if found, 
// return null on error or if not found 


public boolean updateCustomer(...) { 
// implement update record here using data 
// from the customerData value object 
// Return true on success, false on failure or 
// error 


public RowSet selectCustomersRS(...) { 
// implement search customers here using the 
// supplied criteria. 
// Return a RowSet.  


public Collection selectCustomersVO(...) { 
// implement search customers here using the 
// supplied criteria. 
// Alternatively, implement to return a Collection  
// of value objects. 

... 



Example 9.5 Customer value Object 

public class Customer implements java.io.Serializable { 
// member variables 
int CustomerNumber; 
String name; 
String streetAddress; 
String city; 
... 

// getter and setter methods... 
... 



Example 9.6 Using a DAO and DAO Factory ?Client Code 

... 
// create the required DAO Factory 
DAOFactory cloudscapeFactory =  
DAOFactory.getDAOFactory(DAOFactory.DAOCLOUDSCAPE); 

// Create a DAO 
CustomerDAO custDAO =  
cloudscapeFactory.getCustomerDAO(); 

// create a new customer 
int newCustNo = custDAO.insertCustomer(...); 

// Find a customer object. Get the value object. 
Customer cust = custDAO.findCustomer(...); 

// modify the values in the value object. 
cust.setAddress(...); 
cust.setEmail(...); 
// update the customer object using the DAO 
custDAO.updateCustomer(cust); 

// delete a customer object 
custDAO.deleteCustomer(...); 
// select all customers in the same city  
Customer criteria=new Customer(); 
criteria.setCity("广州"); 
Collection customersList =  
custDAO.selectCustomersVO(criteria); 
// returns customersList - collection of Customer 
// value objects. iterate through this collection to 
// get values. 

... 






  
  
   
haohao   2004-07-31 21:18:55 阅读:1933  评论:0  引用:0
   
                                            ――《加西亚哈伯特》有感
   带着微微的灯光,开始了回忆《加西亚哈伯特》书中的故事,要是还没有记错的话,那是在大学一个傍晚,在余老师办公桌上随手翻起的那本书就是《加西亚哈伯特》。
    书中的故事到现在我已经忘的所剩无几了,然而有句话一直铭记在心.那就是,当你牢骚满腹的时候不访看一看老板定理:第一条,老板永远是对的,第二条,当老板不对的时,请参照第一条。
    就在当时我想无非不就时让你做一个忠实的奴隶吗?这个印象一直到年初,也就是来实习之前。
    实习生活改变了我对这句话起初的认识。
    其实这不是一种奴役是一种特有的服从,一种互利.
    在这个商品竞争的社会,人是否在某种意义上也变成了商品,商品就是通过交换来实现起自身价值的;我说人之所以说带有商品的面孔,就是因为他也是通过交换他的劳动来实现自己的价值
   优秀的商品之所以能够在生存下来并站稳脚跟,就是因为他迎的消费者的认同,服从了市场;人也一样要是想在这个社会生存下来,就必须把自己推销出去,要想把自己推销出去,就必须要赢得别人的信任,要想赢得别人的信任就要服从自己的潜意识,服从于自己的信念.
    如果说一个人想的和做的完全是两码事这话,可以注定他将会一事无成,就是成功也是短暂的.因为他连自己都无法服从的话怎么来服从别人怎么来服从于市场,怎么来赢得消费者呢?就是赢得也是短暂的.这就好比一个口是心非的男人用自己的话言巧语去哄骗一个女孩,就是他们好上了那也是短暂的,难道会有一个女孩会喜欢一口是心非的男人吗.? 
   做企业也就是如同杨卓舒先生所说也是一种服从,是一种更高意义上的服从,最起码员工必须要服从于老板,老板也必须要服从于所有员工利益,整个企业必须要服从市场。
   他说正是我杨卓舒服从于石家庄市人民,他们接受了我,接受他们卓达提供的产品才有了今天卓达
   这就使我不由的就想起当年在改革开放的大风大浪中,出现了一位当时被称为“中国改革的风云人物”而后又被评为“中国首富”的天津南德(集团)总裁的牟其中,他的传奇经历以及当时几项“中国第一”,再经媒体大肆的吹捧,使得他一夜之间成为中国知名的“重要人物”,也使得他飘飘然起来,大言不惭地要到美国收购几家大型银行,要在短期内,使得南德集团的资产达到2000亿!
   历史是无情的,而今的牟其中又再次入狱,而他的所谓南德数亿资产,大多数全靠诈骗银行与客户而来的,其中诈骗银行的资金达到数以亿计。 
   象南德集团这样诈骗行为,没有去真正的去服从于真正的资本市场;象这样做,就是做的再传奇也是短暂的。无论谁无论是那家企业它又能这样在是市场是上站稳脚跟呢?怎么能够有人去得到别人真正长期的接受呢?
   这就要我们唤起信时代的罗文,唤起那就和罗文一样服从于自己总统,一样服从于我们现代市场经济下的商品、员工、企业家、企业。
    灯光依然微弱我也该服从自己,疲倦了,该睡觉了.
haohao   2004-07-30 21:06:14 阅读:1281  评论:0  引用:0
package dbsql;  
import java.sql.*;      
import javax.naming.*;      
import java.sql.*;      
import javax.sql.*;      
import java.math.BigDecimal;      
import  java.util.*;      
import  java.text.*;      
public class   dbsql  
{     
     InitialContext ic =null;  
     DataSource ds =null;  
     Connection conn = null;   
     public boolean  con()  throws SQLException   
     {  
       try{  
         ic = new InitialContext();  
         ds = (DataSource) ic.lookup("java:/OracleDS");  
         conn = ds.getConnection();  
      }  
       catch (Exception sqle)   
       {  
        sqle.printStackTrace();  
        return false;  
        }  
        return true;  
     }  
  public ResultSet createExcuteQuery(String sql) throws SQLException {  
     try{ 
  Statement      pstmt = conn.createStatement();  
  ResultSet      rs = pstmt.executeQuery(sql);  
 } 
    catch( Exception sqle ) {      
                sqle.printStackTrace();      
                return null;   
                                       }   
    finally         
       {   
   return rs;   
   rs.close(); 
   pstmt.close(); 
         }         
  } //end of  PrepareExcuteQuery   
  }  
  public ResultSet  PrepareExcuteQuery(String sql) throws SQLException     
{         try{    
             PreparedStatement pstmt = conn.prepareStatement(sql);        
             ResultSet rs = pstmt.executeQuery();     
                }      
catch( Exception sqle ) {      
                sqle.printStackTrace();      
                return null;   
                                       }   
    finally         
       {   
   return rs;   
   rs.close(); 
   pstmt.close(); 
         }         
  } //end of  PrepareExcuteQuery   
  public  int createExecuteUpdate (String sql)throws SQLException     
   {      
 try{ 
   Statement pstmt = conn.createStatement();        
    int sum= pstmt.executeUpdate( sql);     
          } 
 catch( Exception sqle ) {      
          sqle.printStackTrace();      
         return 0;   
                                       }   
    finally         
       {   
   return sum;      
  pstmt.close(); 
               
        }         
   }   
   public  int   PrepareExcuteUpdate(String sql)throws SQLException     
{      
      try {   
     PreparedStatement pstmt = conn.prepareStatement(sql);       
     int sum= pstmt.executeUpdate();   
   } 
   catch( Exception sqle ) {      
          sqle.printStackTrace();      
         return 0;   
      }   
    finally         
       {   
   return sum;      
  pstmt.close(); 
               
        }         
     

 public boolean createExecute(String sql)throws SQLException     
 {       
   try {      
     Statement pstmt = conn.createStatement();        
     pstmt.execute(sql);       
          }     
       catch( Exception sqle ) {      
          sqle.printStackTrace();      
         return false;   
          }     
        finally         
      { 
      return true;           
      pstmt.close(); 
  
      }         
   }    
   public boolean PrepareExecute(String sql) throws SQLException          
      {         
       try         
       {