Ray.wen

好好学习,天天向上

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  21 随笔 :: 0 文章 :: 8 评论 :: 0 引用

置顶随笔 #

摘要: 转载自:http://www.infoq.com/cn/articles/programmer-interview1月13日,著名博客作者Jurgen Appelo写了一篇博文:“软件开发者面试百问”。该文甚受读者欢迎,15日便登上了delicious,Popurls.com,Reddit的首页。InfoQ中文站在得到作者许可之后,将其全文翻译为中文,希望可以对国内读者有所...阅读全文
posted @ 2009-02-05 14:40 田了你 阅读(80) 评论(0) 编辑

2010年1月23日 #

1、有一次我去漫吧租了本金田一,刚看到第二页就泪流满面,不知哪个天杀的用蓝色圆珠笔在某个人物上画了一个圈,写上,这个就是凶手……

2、那天在朋友家,手机不知道放哪儿找不到了,就借朋友他女朋友的手机拨一下,听听在哪儿。输入我的号,一按拨出键,屏幕上显示出她保存的我的名字:NB3(继而感到欣慰,还好是个季军……)

3、今天在学校开小组会议,突然意外的打了个喷嚏,抬起头的时候发现鼻涕飚到前面女生的后背上了,该女并没有觉察,于是偷偷的想帮她抹掉,刚把手伸上去,旁边的女生发现了,大叫:“你这人怎么把鼻涕抹人家身上啊!!??”

5、上大学那会同学聚餐,喝酒一杯接一杯的干,一会胃里就有反应了。。。
冲到厕所,还没站稳就喷涌而出,满满一地呀。。。。
簌簌口回去坐下,没事人一样。
过了一会,好友起身说要上厕所,
我好心劝告:“别去了,刚有人吐过,太恶心了。”

6、下午上公交车,拿出公交卡咣当投进投币孔里了

7、中学的时候,一次作业做的不好,作业本上老师给我批的2个字:“重做”。
第2天早上我去买早点了,然后就把作业本给同桌叫他帮我交。
最经典的地方出现了,他老人家在重做后面写了个“不做”,交了,
接下来,就一悲剧……
更悲剧的是快毕业了,他才告诉我……

8、走在拥挤的街上背后忽然响起急促霸道的鸣笛声,还没反应过来,一辆别克商用车就撞上了我的肩膀;我没发火,只是轻轻的拿出钥匙,在它前进的过程中从头到尾的划了道优美

9、在一地摊上买袜子,一块一双,便宜,本来想买三十双,结果只剩下同一黑色款式的了,卖袜子的忽悠我说,一种颜色好,丢了一只拿其它的顶上谁也看不出来……一想也对,于是买了三十双……

就这样两天一换的……

结果过了快两个月,我同桌实在看不下去了,说:懒死你了,怎么两个月你连袜子也不说换一双

我:……

10、最近降温了,在高速公路上看到一个强人,开了辆敞蓬跑车,戴了个摩托车头盔。

11、一时兴起、拿自己照片当电脑桌面……然后我的电脑就中毒了……

12、高中一同学说梦话
“爱妃,爱妃,不要离开朕……”
我石化……

过一会
“堂堂大清国就这么灭亡了,朕不甘心呐,朕不甘心呐……”
我直接崩溃……

13、说个我老婆的事吧
前天老婆上网要找个财务软件,我就把电脑让给她,我在旁边看,老婆熟练的打开www.google.com,在搜索栏输入“百度”,然后在搜索结果中打开百度,继续找她要的东西——
现在,我要找什么东西都会跟老婆说,去google百度一下……

14、说个同学父母的。
他父母刚开始恋爱。
有天去逛街,他妈看上一件羽绒服,但是一看价钱就拉他爸走。
他爸说:咱买不起还不能试试?
他爸就硬把他妈塞进换衣间。
他妈换出来,他爸东看看西瞅瞅,拉着他妈就跑,说:快跑!趁营业员不在!
他妈穿着那件羽绒服,标签飘在外面,被他爸拖着向外飞奔,刚好路过一个柱子,他妈一把抱着柱子大哭。
他爸回过头严肃的说:快跑!你是不是等着被抓啊?
他妈哭得更凶了。
然后他爸大笑起来:哈哈哈哈……衣服钱你进去的时候我都付过了。

15、批作业,看到学生做几何题没有画图,随手批注:无图无真相……

16、女友想查话费,给10086发短信:我的话费还剩多少

17、同学A出车祸,脚骨折,住院

我们几个玩得好的同学去看他

一进住院部就遇见了他爸妈

我连忙上前去询问A的病情

结果一开口就变成了

“叔叔阿姨,A是怎么死得啊?……”

他爸妈脸都绿了……

18、上高中的时候,最搞笑的一件事情
那会没钱,我们经常凑钱买烟,那天我和我伙计两人买了一盒烟
刚准备去厕所抽,结果上课了,是班主任的课,算了先上课吧
上课的时候就看到那家伙鬼鬼祟祟的写纸条,然后揉了一个大团,给我扔了过来
被班主任看到了,班主任直接下来收走了,站在讲台上开始念
汗ing,我要是知道上面写的是啥,我宁可吞了也不给她
班主任一张嘴:“牦牛(我的外号,如果糗百上有我同学就能认出我了)”,全班爆笑……
“这包烟先给ZJ拿两根”全班继续爆笑……除了ZJ
“再给老大(一同学外号,并非是真的什么老大)拿两根”全班继续爆笑……除了ZJ和老大
“剩下咱两平分”全班同学已经笑的肚子疼了……
最经典的出现了
“你要盒的话少一根,不要盒的话多一根”全班直接笑倒……
我彻底无语了……囧RZ

19、我室友捉弄我,把我钱包藏在一个小盒子里,MD问题是那个小盒子是我要寄给广州一个女网友的礼物,我太牛了寄出去两天后才发现自己钱包没了。我在武汉,我的身份证,银行卡,女朋友的照片全在广州的女网友手里。

20、昨天在沃尔玛,突然闹肚子,强忍着冲进卫生间,刚一蹲下就开始惊天动地的喷发,结果隔壁的小孩大哭起来,她妈问她怎么了,她说,臭~~

21、抵达沿海,卸载完毕。演习任务是配属某守备师进行抗登陆演习,大伙立马进行车辆准备。我正在用黄油枪给负重轮注油,胖胖的师政委站在我身后看了一会,关切道:小同志,辛苦啦!没想到坦克有12个轮子要打气,坦克兵真不容易呀!
我被感动的哭笑不得。

22、上高中的时候总是下课大家聚在一起抽烟
那天我正好有个比较得意的事情给大家讲,结果我就抽的慢
其他人都抽完了,我还剩半根,一看快上课了,大口吸了两口
突然班主任进来了,我把烟一把扔到地上,用脚一踩
可是刚吸进去的两口烟只好屏住呼吸
班主任已经看到了,过来问我,你是不是抽烟呢
我摇头
班主任:说话
继续摇头
班主任怒了:你给我说话
我:我……没……抽……烟……(伴随着烟从鼻子口中不断的喷涌)
班主任也没憋住笑了……

23、今天,下班和同事一起去吃饭,我俩点了一盘辣椒炒鸡蛋,发现里面有根头发,然后同事就用筷子夹起头发,大喊,老板~~你看看这是什么?老板一看,哦了一声~就喊到,来呀!给这位小姐换双筷子

24、在网上花50块钱买了一块手工做的洗脸香皂,用了没两天,晚上再想用的时候发现已经薄了一半了,上面还都是肥皂泡,气得我吐血。

我老爸还说,你这个肥皂真好用,洗完澡浑身滑溜溜的。

25、第一次去吃意大利比萨,不知道吃啥,就点了份38元加8元送一份芝士的套餐。
餐毕,发现少了点什么,一想,原来少了份芝士,

于是叫喊道:服务员,我的那份芝士怎么还没上啊?我都吃完了,还让不让人吃了?
服务员:先生,你的那芝士已经浇在你的比萨了……
我:没事,你去忙吧……

26、中午回到宿舍,看见我杯子里有可乐,直接一口全喝了。喝完我脸都绿了。原来宿舍那哥们吃饺子买了一袋醋,没地方倒,用我杯子装了……
27、老师讲题喜欢投身其中,一天老师讲题:“我的底面半径是20cm,我的高是50cm,那么我——”
下面有人接话说:“是饭桶……”

28、我这人比较丢三落四的,昨晚洗完澡又忘了关煤气……
然后我妈就一边帮我收拾残局一边说:所以你绝对不能犯罪,因为肯定会留下犯罪证据……

29、一日上完体育课,肚子饿的不行,跑到餐厅吃饭,人多,太拥挤,也乱,我就对打饭的大婶喊:"我的饭速度点啊!",大婶就对里面做饭的人喊:“里面的快点!要饭的等急了!”

30、我掏口袋的时候,一把钥匙掉了,当时没有发现,后来回去找!
在路边有对小情侣在那里,男的突然激动的说:是谁的?到底是谁的?
我当时以为是钥匙连忙说:我的,我的!是我的!
后来才知道,原来那女的怀孕了……
可怜我的脸啊……疼了几天

31、我高二隔壁般的真人真事……
某甲在上课睡觉……
被老师发现
他火大……就叫甲到黑板前面解题目……
不会写的话就准备当众羞辱甲
其实甲没走到黑板老师就开始酸他了
成绩那么差还敢上课睡觉真不知羞耻
脑袋是不是放在家里……整天只会睡……

没想到,他居然会写……还解得很漂亮……

老师有点下不了台……只好让他回座位不要管他好了……
没想到他居然还跟老师呛了一句……

我先睡一下,你待会还有不会的再问我

32、我弟弟去某小学打篮球,听到一低年级女生问一个低年级男生:“你到底爱不爱我???”那男生无奈道:“我妈一天给我3元钱,其中两块五都让你拿去买零食了,你说我爱不爱你……

33、话说,我女友打暑期工,在某移动手机广场卖手机
某日中午,午饭时间,卖场几乎没人,我女友旁边柜台来了一位大叔级的人看手机,正好那节柜台的MM还没吃饭,有气无力的,看着那大叔也不像买手机的主儿,就没起来用手臂放在柜台上支着头,因为此MM胸(河蟹)部比较大,该大叔看着看着突然发现可以看到MM的乳(河蟹)沟,眼都看直了,我媳妇发现了,想提醒一下那个MM,结果MM毫无反应,几分钟后,MM开口:大哥,看够了吗?看够了就买个手机吧……
结果大叔二话没说,买了个手机就夺门而逃了……

34、听朋友说的,他一个同事的亲戚来厦门,亲戚给了一张厦门e卡通,上公车,此人给司机看了一下e卡通,就想去找位置了,司机叫住他,说:“读卡啊。”他就拿起e卡通,大声念到:“厦门e卡通~~”司机说:“到那边读。”这人居然直接走到司机指的地方,用尽全力念道:“厦门e卡通!”……车子当场失控

35、有一天我在厕所(学校宿舍的厕所,蹲位)便便,蹲的时间太久了腿有点麻,于是就把手撑着门保持平衡,然后感觉又一条便便要出来了,于是就开始用力,不知不觉手上也用了力,结果……我X,门锁破了,我就滚了出去。

你能想你当时在外面的同学的同学看到的场景吗?!一个光(河蟹)腚的同学突然从厕所里滚了出来,同时还伴随着一条便便从他PP里喷射而出,绝对震撼!!!而且大家一个楼层的,基本上都认识,我X!!这辈子在这帮同学面前抬不起头了……

36、早上老公把我送到单位就走了,然后我突然收到他的短信:“我刚把那个贱(河蟹)人送走,马上就去找你,亲爱的。”

37、早上公交车身边坐着一位带口罩的MM而且是靠窗的位置,现在不是流感闹的很凶吗,所以也就没觉得有什么。大家都知道现在冬天了人多公交车窗户也都关着,车上的气味自然差了一些大家都皱着眉头。可那MM的神态到很自然只见她从兜里掏出一支吸管放在嘴角边并把窗户打开一道缝隙,贪婪的吸着外面的空气。。。。。此举绝非一般人啊=。=

38、我们数学老师总喜欢故作幽默的说些个没人笑的笑话
我们全班就商量恶搞他一把,等他上课说第一句话的时候,我们就全体齐声大笑
那天他进来,沉默了一下说他爸去世了
我立刻放声大笑,其他人鸦雀无声。

39、逛超市呢
看到一收款员在很认真数一堆硬币
一小孩跑过,边跑边唱:门前大桥下游过一群鸭,快来快来数一数,二四六七八。。。。
然后收款员很郁闷的把数了一半的硬币倒回去重数……

40、高中的时候住校,有同学回家让他帮我捎点东西,便发短信:给我烧点衣服和钱。

41、和女友约会,看到前面有个和我女友很像的了,就上去拍了下她屁股。
她一转头就给了我一巴掌。
这时有人拍我肩膀……
我一转头女友就给了我一巴掌。

42、那天突然接一个电话:“猜猜我是谁?猜中有礼物哦!”
我把可能的人都猜了一遍,还不对。后来我怒了,问“你TM到底是谁?不说我挂电话了!”
结果那人说:“我是送快递的,你有一个包裹……”
当时我就吐血了。

43、昨天上午,一个二十多年没见过面的战友突然打电话到我的办公室说:“老战友,知道我是谁吗?”
我当然不知道他是谁了,他是安徽歙县人,在当地一家外资企业上班。最近我们这里的一家蔬菜脱水企业和他们公司联合开发一种新产品,他作为外企技术员工派驻到我们兴化的这家企业。
这消息确实太突然了,我们俩在部队的时候无话不说,感情特别好。前几年失去联系,想不到他突然到我们兴化来了。我在电话里告诉他,我马上到他们的协作单位去接他,中午聚一下。
我到了他们的协作单位,好家伙!公司真有气派,管理方式全是外资模式,刚进公司的大门,保卫就盘问了一气,登记、签字特别严格,大概我那位战友是派驻单位的人,门卫才同意我进公司。
我走到老战友所说的车间,老战友看到了我,朝我点了点头,做了个鬼脸。那意思我看明白了,还没到下班时间,不允许会客,让我在边上等一会。
我闲得无聊,在车间里转了一会,从袋子里掏出一份报纸在车间门边上看了起来。突然有个老板模样的人走到我身后,旁边还站着一个保安,他看了看我,拍拍我的肩膀说:“你一个月的工资是多少?”
我很有礼貌地笑了笑,说:“不多,一千六吧。”那个老板模样的人二话不说,从包里数出了一千六百块钱甩给我,说:“这是你这个月的工资,你被解雇了,请你马上从这里消失。”说完这话他头也不回地走了。
那个保安很不客气地把我推出了公司大门,我挣扎着问:“那人是谁呀?”
“是谁?那是老板,你连他都不认识还在这里混什么混。”……

44、我是一名护士,一天上夜班,半夜的时候突然想起来种的菜没收,怕被别人偷去,就打电话给妹妹让她帮我收,顺便再偷点别人的,打完电话就去给病人送口服药,我轻轻的进了房间,轻轻的拍醒病人,并轻轻的说:大爷,起来偷菜吧!

45、昨晚煮螃蟹,水开后,我把螃蟹一个个扔进锅里。蟹子很新鲜,在锅里乱动。
老婆打小心善,就见不得这个,遂躲在我身后捂着眼睛不敢看。
我宽慰道:佳佳,我们是不是太残忍了?
老婆:嗯…………放盐了吗?

46、今天坐公交车,有一站司机问了一句:“关后门了啊!”没人回答,于是他就关了后门,起步。这是车厢里发出一个女生弱弱的一声:“开门!”司机恼怒地刹车,咣当打开后门,吼道:“要下快下!”车上人都看着后门,半天却没有人下,面面相觑不知怎么回事。
这时车载电视里的女人又发出一声:“开门啊!”

47、我在公交车上放了一个屁,
见身边的纷纷挥手,表情痛苦,
我也挥挥手。
旁边的女士扭过头对我说:你就不要装了

48、端午节要到了,单位发了一箱牛奶和一袋上好泰国香米,单位一女同事下班后让我帮忙帮他搬回家,到楼下后,同事对我说:“打电话无人接,你在楼下等等我,我上去看看,要是我老公在,我就叫他下来搬,若是他不在,那就得麻烦你帮我搬上去。”大家都是朋友,我点了点头也没说什么。

过了一会儿,女同事站在她家的阳台上朝下叫:“你上来哎!”
我第一下没听到,没有反应。就听到我那女同事大声的叫:“哎!我老公不在家,快点上来!”
此话一出,惊动了左邻右舍,都是下班了刚回家,家里都是人,大家都跑到阳台上来看。搞得我在众目睽睽上也不是,下也不是,走了更不是,NND,那小区里还有不少人认识我。便想提醒她,不要喊了:“你说什么啊?”。谁知我那女同事不但没反应过来,还以为我没有听清楚,双手做了一个喇叭状放在嘴巴边更大声的一字一句的叫道:“听到啦?我老公不在家,快点上来,等急了吧!”

49、武汉大学丑闻频出,不知道这个算不算——武大有个周易课,老师拿着个罗盘进来,围着教室神神叨叨地转了一圈,然后,吐出一句话:同学们,今天不宜上课,放学

50、一天半夜四点多一朋友打电话来说了一句话:“那个,我刚看到手机上有你一个去年的未接来电所以打来问问你有啥事。”
我顿时无语了

51、小学的时候,我一男同学,走路上的时候捡到一张纸,打开一看不得了了,是一张写着诅咒的话的纸,上面说如果你明天不把这张纸的内容抄50遍发给别人的话,就会死的很难看等等等等。给我那同学吓的,回家就赶紧连夜抄了50份。第二天发给别人,一开始发出去几张,可是后来大家知道是什么了,说什么也不要他递过来的纸,就这样一上午过去了,他手里还积了好几十份。
下午第一堂音乐课,老师正巧点到他名字让他唱歌了,只见小男生泪眼婆娑的站起来,幽幽的说:“都快死的人了……哪有心情唱歌啊……”

52、我一高中同学毕业后去高速路口当了收费员。一天,有个日本人来他窗口问路。日本人一口流利的英文让他一句都没听懂,但一颗强烈的爱国心告诉他不能日本人面前丢人,于是他一味地微笑着点头道:“yes,yes,yes~!”然后那个日本人骑着自行车就上了高速!

53、我和老婆去卧佛寺游玩,老婆路上走不动,于是我背她。
一个老婆婆看见了,严肃的说:看你也是读过书的人。老婆有病还是早点去医院,拜佛是没用的

54、同学们出游,爬到山顶,一女生特兴奋的站在山顶大喊:祖国啊,我的母亲!然后一暗恋此女的男生特振奋的大喊:祖国啊,我的丈母娘!

55、我家的房子出租给了一个日本客人,一天,那个客人打了我一个电话,用一口不是很流利的中文说道:“陈殿(sang),家里的天然气快没了,能不能帮我加一下!”由于平时客人很少有事麻烦我,所以我心里特别希望不要因为房屋的原因给他带来不便,就顺口问了句:“黑川殿(sang),那你现在断气了没有?”@#……%¥@#,话一出口就觉得不对劲,还好是日本人,不懂中文的“精髓”,居然回了句:“现在还没断气,估计三天之内要断气的!”(o!o)

56、小学时候每天只有几毛钱的零花钱,有一次攒了几天,好不容易买了一包五香瓜子,上课的时候偷偷的全磕了,瓜子壳全放在课桌抽屉了,下午来上课的时候看着瓜子壳又馋了,于是把瓜子壳又放到嘴里都含了一遍,感觉味道好好啊。。

下课的时候一个同学问我吃什么,我只好说吃瓜子壳,专门买的五香瓜子壳,只有壳没有肉的,就是吃味道的。。结果那一个下午一帮子同学围在我座位边上吃我舔过两遍的瓜子壳。。。。

57、上学的时候学校是平房,九月份开学,来了好多新生。一天一个新生好像是课代表捧着一堆作业,问我:“数学办公室在哪?”
“男厕边上。”数学办公室确实在男厕边上,不过是左边。
那位老兄走到了男厕右边对着门喊“报告”
停顿了一下,里面传出个声音“不许进!”

58、我爹娘说,我小的时候和他们一起住宾馆,早上起来他们发现我很乖巧地拿牙刷刷牙,问题是宾馆的洗手池比我人还高,他们就问我怎么装到水,我带他们走进厕所,指着马桶……

59、高中军训后,第一天上课,是语文课。
同桌没休息过来,上课时睡觉。
老师见到,“睡觉的那个同学,
请你来回答一下这个问题。”
同桌一激灵醒了,“我不会……”
老师:“注意听讲,不要再睡了,
坐下!那么由53号同学来回答这个问题。”
同桌又站起:“老师,我不会……”
老师晕,“坐下,那么由×××同学来回答!”

同桌遂站起:“老师,我真的不会!”
“坐下!语文课代表给我起来回答!”
同桌再次站起:“老师,我就是语文课代表……”

60、下车棚取车,见四下无人,就很豪迈的放了个P,结果引起隔壁电摩防盗器巨响

61、坐公汽,我坐在前排靠窗的位置。
半小时后,我把头伸出窗外。
后排也有一哥儿们,头伸在窗外。
我对他喊:“把头缩进去。”
那哥儿们看来不是盏省油的灯,横着眼睛说:“去,关你屁事。”
我缩回头,那哥儿们也缩回,我转头非常礼貌地对他说:“请再不要把头伸出窗外。”
我第二次把头伸出窗外。
估计那哥儿们特有自尊,他觉得,你能伸,我也伸得,就又一次把头伸出窗外。
我再也憋不住,呕了,脏物糊了那哥儿一脸。
那哥儿狂叫一声,我旁边的朋友,膀大腰圆,对那哥儿说:“叫什么叫,人家给你打过招呼的。”

62、高中的时候喜欢踢球,GF经常看我踢,有次我在练习射门柱,她跑过说:“我站那你能踢倒我么?”(大概15米左右)我说试试吧!
结果不知哪根经抽到了,一个大力抽射,直接爆头!!
当场大哭,为这事一个礼拜不跟我说话!

63、我跟朋友说我的自行车丢了,买了还不到一星期,伤心。
朋友说你那算啥,我买了一辆自行车,只看了一眼就丢了:

朋友托别人买自行车,中午十二点多点,他正在厨房炒菜,只听楼下有人喊:“X科长,车子买回来了!”
朋友从窗户上探出头来看了看说:“放在那儿吧,我这就下去,谢谢了啊!”

关火,擦擦手,下楼。
NND,车没了……

64、买了一个ipodtouch,我一个朋友和我说屏幕很硬,不用贴膜,钥匙划都没事。。然后我就用钥匙划了一下。草

65、有一次,上课铃响后,一男生风风火火的冲进教室,冲到最后一排,老师发话了:有的同学迟到了,就从后门进来,不要影响别人!男生坐下后,那出包子,咬了一口。他发现旁边有个漂亮MM,一直盯着她。他自以为MM也没吃早饭,于是,殷勤的把包子给了她。老师又发话了,这次脸色难看了:有的同学迟到就算了,还在课堂吃早饭,自己吃也算了,就不要把包子给听课老师了嘛!  
posted @ 2010-01-23 13:55 田了你 阅读(17) 评论(0) 编辑

2009年2月18日 #

1. 引言

  近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机

  应用程序已从传统的桌面应用转到Web应用。基于B/S(Browser/Server)架构的3层开发模式逐渐取代C/S(Client/Server)架构的开发模式,成为开发企业级应用和电子商务普遍采用的技术。在Web应用开发的早期,主要使用的技术是CGIASPPHP等。之后,Sun公司推出了基于Java语言的Servlet+Jsp+JavaBean技术。相比传统的开发技术,它具有跨平台﹑安全﹑有效﹑可移植等特性,这使其更便于使用和开发。

  Java应用程序访问数据库的基本原理

  在Java语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁,

  即Java语言通过JDBC技术访问数据库。JDBC是一种“开放”的方案,它为数据库应用开发人员﹑数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以用纯Java语言编写完整的数据库应用程序。JDBC提供两种API,分别是面向开发人员的API和面向底层的JDBC驱动程序API,底层主要通过直接的JDBC驱动和JDBC-ODBC桥驱动实现与数据库的连接。

  一般来说,Java应用程序访问数据库的过程(如图1所示)是:

  ①装载数据库驱动程序;

  ②通过JDBC建立数据库连接;

  ③访问数据库,执行SQL语句;

  ④断开数据库连接。


图1 Java数据库访问机制
  JDBC作为一种数据库访问技术,具有简单易用的优点。但使用这种模式进行Web应用
  程序开发,存在很多问题:首先,每一次Web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的Web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
 
  数据库连接池(connection pool)的工作原理
  1、基本概念及原理
由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,
  对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。连接池的基本工作原理见下图2。

图2 连接池的基本工作原理
  2、服务器自带的连接池
  JDBC的API中没有提供连接池的方法。一些大型的WEB应用服务器如BEA的WebLogic和IBM的WebSphere等提供了连接池的机制,但是必须有其第三方的专用类方法支持连接池的用法。
  连接池关键问题分析
  1、并发问题
  为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java语言自身提供了对并发管理的支持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如:
public synchronized Connection getConnection()
  2、多数据库服务器和多用户
  对于大型的企业级应用,常常需要同时连接不同的数据库(如连接OracleSybase)。如何连接不同的数据库呢?我们采用的策略是:设计一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址(<poolName.url>)﹑用户名(<poolName.user>)﹑密码(<poolName.password>)等信息。如tx.url=192.168.1.123:5000/tx_it,tx.user=cyl,tx.password=123456。根据资源文件提供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连接池。
  对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。
  3、事务处理
  我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。
Java语言中,Connection类本身提供了对事务的支持,可以通过设置Connection的AutoCommit属性为false,然后显式的调用commit或rollback方法来实现。但要高效的进行Connection复用,就必须提供相应的事务支持机制。可采用每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。
  4、连接池的分配与释放
  连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
  对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果等待时间超过预定时间timeout,则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。
  5、连接池的配置与维护
  连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。
  如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
连接池的实现
  1、连接池模型
  本文讨论的连接池包括一个连接池类(DBConnectionPool)和一个连接池管理类(DBConnetionPoolManager)和一个配置文件操作类(ParseDSConfig)。连接池类是对某一数据库所有连接的“缓冲池”,主要实现以下功能:①从连接池获取或创建可用连接;②使用完毕之后,把连接返还给连接池;③在系统关闭前,断开所有连接并释放连接占用的系统资源;④还能够处理无效连接(原来登记为可用的连接,由于某种原因不再可用,如超时,通讯问题),并能够限制连接池中的连接总数不低于某个预定值和不超过某个预定值。(5)当多数据库时,且数据库是动态增加的话,将会加到配置文件中。
  连接池管理类是连接池类的外覆类(wrapper),符合单例模式,即系统中只能有一个连接池管理类的实例。其主要用于对多个连接池对象的管理,具有以下功能:①装载并注册特定数据库的JDBC驱动程序;②根据属性文件给定的信息,创建连接池对象;③为方便管理多个连接池对象,为每一个连接池对象取一个名字,实现连接池名字与其实例之间的映射;④跟踪客户使用连接情况,以便需要是关闭连接释放资源。连接池管理类的引入主要是为了方便对多个连接池的使用和管理,如系统需要连接不同的数据库,或连接相同的数据库但由于安全性问题,需要不同的用户使用不同的名称和密码。
         2、连接池实现(经过本人改版,可以适用多数据库类型的应用以及一种数据库类型多个数据库且数据  库的数量可以动态增加的应用程序)
         1),DBConnectionPool.java   数据库连接池类
         2),DBConnectionManager .java   数据库管理类
         3),DSConfigBean .java                单个数据库连接信息Bean
         4),ParseDSConfig.java                操作多(这个'多'包括不同的数据库和同一种数据库有多个数据库)
                                                            数据 配置文件xml
         5),ds.config.xml                           数据库配置文件xml
         原代码如下: 
        DBConnectionPool.java  
        ----------------------------------------------------------
      /**
 * 数据库连接池类
 */
package com.chunkyo.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
/**
 * @author chenyanlin
 *
 */
public class DBConnectionPool implements TimerListener {
 private Connection con=null;
 private int inUsed=0;    //使用的连接数
 private ArrayList freeConnections = new ArrayList();//容器,空闲连接
 private int minConn;     //最小连接数
 private int maxConn;     //最大连接
 private String name;     //连接池名字
 private String password; //密码
 private String url;      //数据库连接地址
 private String driver;   //驱动
 private String user;     //用户名
 public Timer timer;      //定时
 /**
  *
  */
 public DBConnectionPool() {
  // TODO Auto-generated constructor stub
 }
 /**
  * 创建连接池
  * @param driver
  * @param name
  * @param URL
  * @param user
  * @param password
  * @param maxConn
  */
 public DBConnectionPool(String name, String driver,String URL, String user, String password, int maxConn)
 {
  this.name=name;
  this.driver=driver;
  this.url=URL;
  this.user=user;
  this.password=password;
  this.maxConn=maxConn;
 }
 /**
  * 用完,释放连接
  * @param con
  */
 public synchronized void freeConnection(Connection con)
 {
  this.freeConnections.add(con);//添加到空闲连接的末尾
  this.inUsed--;
 }
 /**
  * timeout  根据timeout得到连接
  * @param timeout
  * @return
  */
 public synchronized Connection getConnection(long timeout)
 {
  Connection con=null;
  if(this.freeConnections.size()>0)
  {
   con=(Connection)this.freeConnections.get(0);
   if(con==null)con=getConnection(timeout); //继续获得连接
  }
  else
  {
   con=newConnection(); //新建连接
  }
  if(this.maxConn==0||this.maxConn<this.inUsed)
  {
   con=null;//达到最大连接数,暂时不能获得连接了。
  }
  if(con!=null)
  {
   this.inUsed++;
  }
  return con;
 }
 /**
  *
  * 从连接池里得到连接
  * @return
  */
 public synchronized Connection getConnection()
 {
  Connection con=null;
  if(this.freeConnections.size()>0)
  {
   con=(Connection)this.freeConnections.get(0);
   this.freeConnections.remove(0);//如果连接分配出去了,就从空闲连接里删除
   if(con==null)con=getConnection(); //继续获得连接
  }
  else
  {
   con=newConnection(); //新建连接
  }
  if(this.maxConn==0||this.maxConn<this.inUsed)
  {
   con=null;//等待 超过最大连接时
  }
  if(con!=null)
  {
   this.inUsed++;
   System.out.println("得到 "+this.name+" 的连接,现有"+inUsed+"个连接在使用!");
  }
  return con;
 }
 /**
  *释放全部连接
  *
  */
 public synchronized void release()
 {
  Iterator allConns=this.freeConnections.iterator();
  while(allConns.hasNext())
  {
   Connection con=(Connection)allConns.next();
   try
   {
    con.close();
   }
   catch(SQLException e)
   {
    e.printStackTrace();
   }
   
  }
  this.freeConnections.clear();
   
 }
 /**
  * 创建新连接
  * @return
  */
 private Connection newConnection()
 {
  try {
   Class.forName(driver);
   con=DriverManager.getConnection(url, user, password);
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("sorry can't find db driver!");
  } catch (SQLException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
   System.out.println("sorry can't create Connection!");
  }
  return con;
  
 }
 /**
  * 定时处理函数
  */
 public synchronized void TimerEvent()
 {
     //暂时还没有实现以后会加上的
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
 /**
  * @return the driver
  */
 public String getDriver() {
  return driver;
 }
 /**
  * @param driver the driver to set
  */
 public void setDriver(String driver) {
  this.driver = driver;
 }
 /**
  * @return the maxConn
  */
 public int getMaxConn() {
  return maxConn;
 }
 /**
  * @param maxConn the maxConn to set
  */
 public void setMaxConn(int maxConn) {
  this.maxConn = maxConn;
 }
 /**
  * @return the minConn
  */
 public int getMinConn() {
  return minConn;
 }
 /**
  * @param minConn the minConn to set
  */
 public void setMinConn(int minConn) {
  this.minConn = minConn;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the password
  */
 public String getPassword() {
  return password;
 }
 /**
  * @param password the password to set
  */
 public void setPassword(String password) {
  this.password = password;
 }
 /**
  * @return the url
  */
 public String getUrl() {
  return url;
 }
 /**
  * @param url the url to set
  */
 public void setUrl(String url) {
  this.url = url;
 }
 /**
  * @return the user
  */
 public String getUser() {
  return user;
 }
 /**
  * @param user the user to set
  */
 public void setUser(String user) {
  this.user = user;
 }
}

-------------------------------------------
 DBConnectionManager .java
------------------------------------------
/**
 * 数据库连接池管理类
 */
package com.chunkyo.db;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
/**
 * @author chenyanlin
 *
 */
public class DBConnectionManager {
 static private DBConnectionManager instance;//唯一数据库连接池管理实例类
 static private int clients;                 //客户连接数
 private Vector drivers  = new Vector();//驱动信息
 private Hashtable pools=new Hashtable();//连接池
 
 /**
  * 实例化管理类
  */
 public DBConnectionManager() {
  // TODO Auto-generated constructor stub
  this.init();
 }
 /**
  * 得到唯一实例管理类
  * @return
  */
 static synchronized public DBConnectionManager getInstance()
 {
  if(instance==null)
  {
   instance=new DBConnectionManager();
  }
  return instance;
  
 }
 /**
  * 释放连接
  * @param name
  * @param con
  */
 public void freeConnection(String name, Connection con)
 {
  DBConnectionPool pool=(DBConnectionPool)pools.get(name);//根据关键名字得到连接池
  if(pool!=null)
  pool.freeConnection(con);//释放连接
 }
 /**
  * 得到一个连接根据连接池的名字name
  * @param name
  * @return
  */
 public Connection getConnection(String name)
 {
  DBConnectionPool pool=null;
  Connection con=null;
  pool=(DBConnectionPool)pools.get(name);//从名字中获取连接池
  con=pool.getConnection();//从选定的连接池中获得连接
  if(con!=null)
  System.out.println("得到连接。。。");
  return con;
 }
 /**
  * 得到一个连接,根据连接池的名字和等待时间
  * @param name
  * @param time
  * @return
  */
 public Connection getConnection(String name, long timeout)
 {
  DBConnectionPool pool=null;
  Connection con=null;
  pool=(DBConnectionPool)pools.get(name);//从名字中获取连接池
  con=pool.getConnection(timeout);//从选定的连接池中获得连接
  System.out.println("得到连接。。。");
  return con;
 }
 /**
  * 释放所有连接
  */
 public synchronized void release()
 {
  Enumeration allpools=pools.elements();
  while(allpools.hasMoreElements())
  {
   DBConnectionPool pool=(DBConnectionPool)allpools.nextElement();
   if(pool!=null)pool.release();
  }
  pools.clear();
 }
 /**
  * 创建连接池
  * @param props
  */
 private void createPools(DSConfigBean dsb)
 {
  DBConnectionPool dbpool=new DBConnectionPool();
  dbpool.setName(dsb.getName());
  dbpool.setDriver(dsb.getDriver());
  dbpool.setUrl(dsb.getUrl());
  dbpool.setUser(dsb.getUsername());
  dbpool.setPassword(dsb.getPassword());
  dbpool.setMaxConn(dsb.getMaxconn());
  System.out.println("ioio:"+dsb.getMaxconn());
  pools.put(dsb.getName(), dbpool);
 }
 /**
  * 初始化连接池的参数
  */
 private void init()
 {
  //加载驱动程序
  this.loadDrivers();
  //创建连接池
  Iterator alldriver=drivers.iterator();
  while(alldriver.hasNext())
  {
   this.createPools((DSConfigBean)alldriver.next());
   System.out.println("创建连接池。。。");
   
  }
  System.out.println("创建连接池完毕。。。");
 }
 /**
  * 加载驱动程序
  * @param props
  */
 private void loadDrivers()
 {
  ParseDSConfig pd=new ParseDSConfig();
 //读取数据库配置文件
  drivers=pd.readConfigInfo("ds.config.xml");
  System.out.println("加载驱动程序。。。");
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
}
----------------------------------------
DSConfigBean.java
----------------------------------------
/**
 * 配置文件Bean类
 */
package com.chunkyo.db;
/**
 * @author chenyanlin
 *
 */
public class DSConfigBean {
 private String type     =""; //数据库类型
 private String name     =""; //连接池名字
 private String driver   =""; //数据库驱动
 private String url      =""; //数据库url
 private String username =""; //用户名
 private String password =""; //密码
 private int maxconn  =0; //最大连接数
 /**
  *
  */
 public DSConfigBean() {
  // TODO Auto-generated constructor stub
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
 /**
  * @return the driver
  */
 public String getDriver() {
  return driver;
 }
 /**
  * @param driver the driver to set
  */
 public void setDriver(String driver) {
  this.driver = driver;
 }
 /**
  * @return the maxconn
  */
 public int getMaxconn() {
  return maxconn;
 }
 /**
  * @param maxconn the maxconn to set
  */
 public void setMaxconn(int maxconn) {
  this.maxconn = maxconn;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the password
  */
 public String getPassword() {
  return password;
 }
 /**
  * @param password the password to set
  */
 public void setPassword(String password) {
  this.password = password;
 }
 /**
  * @return the type
  */
 public String getType() {
  return type;
 }
 /**
  * @param type the type to set
  */
 public void setType(String type) {
  this.type = type;
 }
 /**
  * @return the url
  */
 public String getUrl() {
  return url;
 }
 /**
  * @param url the url to set
  */
 public void setUrl(String url) {
  this.url = url;
 }
 /**
  * @return the username
  */
 public String getUsername() {
  return username;
 }
 /**
  * @param username the username to set
  */
 public void setUsername(String username) {
  this.username = username;
 }
}
-----------------------------------------------------
ParseDSConfig.java
-----------------------------------------------------
/**
 * 操作配置文件类 读  写 修改 删除等操作
 */
package com.chunkyo.db;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
 * @author chenyanlin
 *
 */
public class ParseDSConfig {
 /**
  * 构造函数
  */
 public ParseDSConfig() {
  // TODO Auto-generated constructor stub
 }
 /**
  * 读取xml配置文件
  * @param path
  * @return
  */
 public Vector readConfigInfo(String path)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  Vector dsConfig=null;
  FileInputStream fi = null;
  try
  {
   fi=new FileInputStream(rpath);//读取路径文件
   dsConfig=new Vector();
   SAXBuilder sb=new SAXBuilder();
   Document doc=sb.build(fi);
   Element root=doc.getRootElement();
   List pools=root.getChildren();
   Element pool=null;
   Iterator allPool=pools.iterator();
   while(allPool.hasNext())
   {
    pool=(Element)allPool.next();
    DSConfigBean dscBean=new DSConfigBean();
    dscBean.setType(pool.getChild("type").getText());
    dscBean.setName(pool.getChild("name").getText());
    System.out.println(dscBean.getName());
    dscBean.setDriver(pool.getChild("driver").getText());
    dscBean.setUrl(pool.getChild("url").getText());
    dscBean.setUsername(pool.getChild("username").getText());
    dscBean.setPassword(pool.getChild("password").getText());
    dscBean.setMaxconn(Integer.parseInt(pool.getChild("maxconn").getText()));
    dsConfig.add(dscBean);
   }
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  finally
  {
   try {
    fi.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  return dsConfig;
 }
/**
 *修改配置文件 没时间写 过段时间再贴上去 其实一样的
 */
 public void modifyConfigInfo(String path,DSConfigBean dsb) throws Exception
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi=null; //读出
  FileOutputStream fo=null; //写入
  
 }
/**
 *增加配置文件
 *
 */
 public void addConfigInfo(String path,DSConfigBean dsb)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi=null;
  FileOutputStream fo=null;
  try
  {
   fi=new FileInputStream(rpath);//读取xml流
   
   SAXBuilder sb=new SAXBuilder();
   
   Document doc=sb.build(fi); //得到xml
   Element root=doc.getRootElement();
   List pools=root.getChildren();//得到xml子树
   
   Element newpool=new Element("pool"); //创建新连接池
   
   Element pooltype=new Element("type"); //设置连接池类型
   pooltype.setText(dsb.getType());
   newpool.addContent(pooltype);
   
   Element poolname=new Element("name");//设置连接池名字
   poolname.setText(dsb.getName());
   newpool.addContent(poolname);
   
   Element pooldriver=new Element("driver"); //设置连接池驱动
   pooldriver.addContent(dsb.getDriver());
   newpool.addContent(pooldriver);
   
   Element poolurl=new Element("url");//设置连接池url
   poolurl.setText(dsb.getUrl());
   newpool.addContent(poolurl);
   
   Element poolusername=new Element("username");//设置连接池用户名
   poolusername.setText(dsb.getUsername());
   newpool.addContent(poolusername);
   
   Element poolpassword=new Element("password");//设置连接池密码
   poolpassword.setText(dsb.getPassword());
   newpool.addContent(poolpassword);
   
   Element poolmaxconn=new Element("maxconn");//设置连接池最大连接
   poolmaxconn.setText(String.valueOf(dsb.getMaxconn()));
   newpool.addContent(poolmaxconn);
   pools.add(newpool);//将child添加到root
   Format format = Format.getPrettyFormat();
      format.setIndent("");
      format.setEncoding("utf-8");
      XMLOutputter outp = new XMLOutputter(format);
      fo = new FileOutputStream(rpath);
      outp.output(doc, fo);
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  finally
  {
   
  }
 }
 /**
  *删除配置文件
  */
 public void delConfigInfo(String path,String name)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi = null;
  FileOutputStream fo=null;
  try
  {
   fi=new FileInputStream(rpath);//读取路径文件
   SAXBuilder sb=new SAXBuilder();
   Document doc=sb.build(fi);
   Element root=doc.getRootElement();
   List pools=root.getChildren();
   Element pool=null;
   Iterator allPool=pools.iterator();
   while(allPool.hasNext())
   {
    pool=(Element)allPool.next();
    if(pool.getChild("name").getText().equals(name))
    {
     pools.remove(pool);
     break;
    }
   }
   Format format = Format.getPrettyFormat();
      format.setIndent("");
      format.setEncoding("utf-8");
      XMLOutputter outp = new XMLOutputter(format);
      fo = new FileOutputStream(rpath);
      outp.output(doc, fo);
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  finally
  {
   try {
    fi.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  ParseDSConfig pd=new ParseDSConfig();
  String path="ds.config.xml";
  pd.readConfigInfo(path);
  //pd.delConfigInfo(path, "tj012006");
  DSConfigBean dsb=new DSConfigBean();
  dsb.setType("oracle");
  dsb.setName("yyy004");
  dsb.setDriver("org.oracle.jdbc");
  dsb.setUrl("jdbc:oracle://localhost");
  dsb.setUsername("sa");
  dsb.setPassword("");
  dsb.setMaxconn(1000);
  pd.addConfigInfo(path, dsb);
  pd.delConfigInfo(path, "yyy001");
 }
}

--------------------------------------
ds.config.xml   配置文件
--------------------------------------


<ds-config>
<pool>
<type>mysql</type>
<name>user</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user</url>
<username>sa</username>
<password>123456</password>
<maxconn>100</maxconn>
</pool>
<pool>
<type>mysql</type>
<name>user2</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user2</url>
<username>sa</username>
<password>1234</password>
<maxconn>10</maxconn>
</pool>
<pool>
<type>sql2000</type>
<name>books</name>
<driver>com.microsoft.sqlserver.driver</driver>
<url>jdbc:sqlserver://localhost:1433/books:databasename=books</url>
<username>sa</username>
<password></password>
<maxconn>100</maxconn>
</pool>
</ds-config>


3. 连接池的使用
  1。Connection的获得和释放
  DBConnectionManager   connectionMan=DBConnectionManager .getInstance();//得到唯一实例
   //得到连接
   String name="mysql";//从上下文得到你要访问的数据库的名字
   Connection  con=connectionMan.getConnection(name);
  //使用
  。。。。。。。
  // 使用完毕
 connectionMan.freeConnection(name,con);//释放,但并未断开连接
 2。数据库连接的动态增加和连接池的动态增加
      1。调用xml操作增加类

      2。重新实例华连接池管理池类
posted @ 2009-02-18 15:39 田了你 阅读(46) 评论(0) 编辑

2009年2月13日 #

1.修改KEY.INI中的TOKEN,在前面分别加一个,如机器1,
第一台:
TOKEN = 40000
CONFIG = 10000
GROUP = 10001
USER = 10002
BASE = 10003
BASECOL = 10004
VIEW = 10005
VIEWCOL = 10006
RIGHT = 10007
FORMAT = 10008
INSTANCE = 10009
那么机器二:TOKEN = 240000
CONFIG = 210000
GROUP = 210001
USER = 210002
BASE = 210003
BASECOL = 210004
VIEW = 210005
VIEWCOL = 210006
RIGHT = 210007
FORMAT = 210008
INSTANCE = 210009

以此类推。

2.安装完后想修改端口(windows):

1)tdbservice.exe安装服务时,指定端口

2)在第2个之后的Server的bin目录下运行,tdbservice -install -name:trs2 -p:port2


posted @ 2009-02-13 15:21 田了你 阅读(25) 评论(0) 编辑

2009年2月5日 #

转载自:http://www.infoq.com/cn/articles/programmer-interview

1月13日,著名博客作者Jurgen Appelo写了一篇博文:“软件开发者面试百问”。该文甚受读者欢迎,15日便登上了delicious,Popurls.com,Reddit的首页。InfoQ中文站在得到作者许可之后,将其全文翻译为中文,希望可以对国内读者有所助益。

以下为文章全文

想雇到搞软件开发的聪明人可不容易。万一一不小心,就会搞到一堆低能大狒狒。我去年就碰到这种事了。你肯定不想这样吧。听我的,没错。在树上开站立会议门都没有。
问点有难度的问题能帮你把聪明人跟狒狒们分开。我决定把我自己整理出来的软件开发者面试百问发出来,希望能帮到你们的忙。
这个列表涵盖了软件工程知识体系中定义的大多数知识域。当然,如果你只想找出类拔萃的程序员,便只需涉及结构、算法、数据结构、测试这几个话题。如果想雇架构师,也可以只考虑需求、功能设计、技术设计这些地方。
不过不管你怎么做,都要牢记一点:
这里大多数问题的答案都没有对错之分!
你可以把我的这些问题作为引子,展开讨论。例如下面有个问题是使用静态方法或是单例的缘由。如果那个面试的就此展开长篇大论,那他很有可能是个聪明能干的家伙!如果他一脸茫然的看着你,发出这种声音,很明显这就是只狒狒了。同样,想知道一个数是不是2的乘方也有很多方法,不过要是面试的人想用mod运算符,嗯……你知道我的意思吧。(你不知道也没关系,来根香蕉?)
需求
  1. 你能给出一些非功能性(或者质量)需求的例子么?
  2. 如果客户需要高性能、使用极其方便而又高度安全,你会给他什么建议?
  3. 你能给出一些用来描述需求的不同技术么?它们各自适用于什么场景?
  4. 需求跟踪是什么意思?什么是向前追溯,什么是向后追溯?
  5. 你喜欢用什么工具跟踪需求?
  6. 你怎么看待需求变化?它是好是坏?给出你的理由。
  7. 你怎样研究需求,发现需求?有哪些资源可以用到?
  8. 你怎么给需求制定优先级?有哪些技术?
  9. 在需求过程中,用户、客户、开发人员各自的职责是什么?
  10. 你怎么对待不完整或是令人费解的需求?
功能设计
  1. 在功能设计中有哪些隐喻?给出几个成功的例子。
  2. 如果有些功能的执行时间很长,怎么能让用户感觉不到太长的等待?
  3. 如果用户必须要在一个很小的区域内,从一个常常的列表中选择多个条目,你会用什么控件?
  4. 有哪些方法可以保证数据项的完整?
  5. 建立系统原型有哪些技术?
  6. 应用程序怎样建立对用户行为的预期?给出一些例子。
  7. 如何入手设计一组数量庞大而又复杂的特性,你能举出一些设计思路吗?
  8. 有一个列表,其中有10个元素,每个元素都有20个字段可以编辑,你怎样设计这种情况?如果是1000个元素,每个元素有3个字段呢?
  9. 用不同的颜色对一段文本中的文字标记高亮,这种做法有什么问题?
  10. Web环境和Windows环境各有些什么限制?
技术设计
  1. 什么是低耦合和高聚合?封装原则又是什么意思?
  2. 在Web应用中,你怎样避免几个人编辑同一段数据所造成的冲突?
  3. 你知道设计模式吗?你用过哪些设计模式?在什么场合下用的?
  4. 是否了解什么是无状态的业务层?长事务如何与之相适应?
  5. 在搭建一个架构,或是技术设计时,你用过几种图?
  6. 在N层架构中都有哪些层?它们各自的职责是什么?
  7. 有哪些方法可以确保架构中数据的正确和健壮?
  8. 面向对象设计和面向组件设计有哪些不同之处?
  9. 怎样在数据库中对用户授权、用户配置、权限管理这几项功能建模?
  10. 怎样按照等级制度给动物王国(包括各种物种和各自的行为)建模?
程序设计
  1. 你怎样保证你的代码可以处理各种错误事件?
  2. 解释一下什么是测试驱动开发,举出极限编程中的一些原则。
  3. 看别人代码的时候,你最关心什么地方?
  4. 什么时候使用抽象类,什么时候使用接口?
  5. 除了IDE以外,你还喜欢哪些必不可少的工具?
  6. 你怎么保证代码执行速度快,而又不出问题?
  7. 什么时候用多态,什么时候用委派?
  8. 什么时候使用带有静态成员的类,什么时候使用单例?
  9. 你在代码里面怎么提前处理需求的变化?给一些例子。
  10. 描述一下实现一段代码的过程,从需求到最终交付。
算法
  1. 怎样知道一个数字是不是2的乘方?怎样判断一个数是不是奇数?
  2. 怎样找出链表中间的元素?
  3. 怎样改变10,000个静态HTML页面中所有电话号码的格式?
  4. 举出一个你所用过的递归的例子。
  5. 在散列表和排序后的列表中找一个元素,哪个查找速度最快?
  6. 不管是书、杂志还是网络,你从中所学到的最后一点算法知识是什么?
  7. 怎样把字符串反转?你能不用临时的字符串么?
  8. 你愿意用什么类型的语言来编写复杂的算法?
  9. 有一个数组,里面是从1到1,000,000的整数,其中有一个数字出现了两次,你怎么找出那个重复的数字?
  10. 你知道“旅行商问题(Traveling Salesman Problem)”么?
数据结构
  1. 怎样在内存中实现伦敦地铁的结构?
  2. 怎样以最有效的方式在数据库中存储颜色值?
  3. 队列和堆栈区别是什么?
  4. 用堆或者栈存储数据的区别是什么?
  5. 怎样在数据库中存储N维向量?
  6. 你倾向于用哪种类型的语言编写复杂的数据结构?
  7. 21的二进制值是什么?十六制值呢?
  8. 不管是书、杂志还是网络,你从中所学到的最后一点数据结构的知识是什么?
  9. 怎样在XML文档中存储足球比赛结果(包括队伍和比分)?
  10. 有哪些文本格式可以保存Unicode字符?
测试
  1. 什么是回归测试?怎样知道新引入的变化没有给现有的功能造成破坏?
  2. 如果业务层和数据层之间有依赖关系,你该怎么写单元测试?
  3. 你用哪些工具测试代码质量?
  4. 在产品部署之后,你最常碰到的是什么类型的问题?
  5. 什么是代码覆盖率?有多少种代码覆盖率?
  6. 功能测试和探索性测试的区别是什么?你怎么对网站进行测试?
  7. 测试套件、测试用例、测试计划,这三者之间的区别是什么?你怎么组织测试?
  8. 要对电子商务网站做冒烟测试,你会做哪些类型的测试?
  9. 客户在验收测试中会发现不满意的东西,怎样减少这种情况的发生?
  10. 你去年在测试和质量保证方面学到了哪些东西?
维护
  1. 你用哪些工具在维护阶段对产品进行监控?
  2. 要想对一个正在产品环境中被使用的产品进行升级,该注意哪些重要事项?
  3. 如果在一个庞大的文件中有错误,而代码又无法逐步跟踪,你怎么找出错误?
  4. 你怎样保证代码中的变化不会影响产品的其他部分?
  5. 你怎样为产品编写技术文档?
  6. 你用过哪些方式保证软件产品容易维护?
  7. 怎样在产品运行的环境中进行系统调试?
  8. 什么是负载均衡?负载均衡的方式有哪些种?
  9. 为什么在应用程序的生命周期中,软件维护费用所占的份额最高?
  10. 再造工程(re-engineering)和逆向工程(reverse engineering)的区别是什么?
配置管理
  1. 你知道配置管理中基线的含义么?怎样把项目中某个重要的时刻冻结?
  2. 你一般会把哪些东西纳入版本控制?
  3. 怎样可以保证团队中每个人都知道谁改变了哪些东西?
  4. Tag和Branch的区别是什么?在什么情况下该使用tag,什么时候用branch?
  5. 怎样管理技术文档——如产品架构文档——的变化?
  6. 你用什么侗剧管理项目中所有数字信息的状态?你最喜欢哪种工具?
  7. 如果客户想要对一款已经发布的产品做出变动,你怎么处理?
  8. 版本管理和发布管理有什么差异?
  9. 对文本文件的变化和二进制文件的变化进行管理,这二者有什么不同?
  10. 同时处理多个变更请求,或是同时进行增量开发和维护,这种事情你怎么看待?
项目管理
  1. 范围、时间、成本,这三项中哪些是可以由客户控制的?
  2. 谁该对项目中所要付出的一切做出估算?谁有权设置最后期限?
  3. 减少交付的次数,或是减少每个每个交付中的工作量,你喜欢哪种做法?
  4. 你喜欢用哪种图来跟踪项目进度?
  5. 迭代和增量的区别在哪里?
  6. 试着解释一下风险管理中用到的实践。风险该如何管理?
  7. 你喜欢任务分解还是滚动式计划?
  8. 你需要哪些东西帮助你判断项目是否符合时间要求,在预算范围内运作?
  9. DSDM、Prince2、Scrum,这三者之间有哪些区别?
  10. 如果客户想要的东西太多,你在范围和时间上怎样跟他达成一致呢?

 

posted @ 2009-02-05 14:40 田了你 阅读(80) 评论(0) 编辑

2009年2月1日 #

新年,新气象。

希望今年能坚持天天写日志。

今天在使用WCM6的模板的时候出现一问题。如下:

问题:

在模板里这样写:

‘<script language="javascript" src="http://www.hechuan.gov.cn/video/videolist.jsp"></script>’
但最后WCM解析后

变成了‘<script language="javascript" src="videolist.jsp" OLDSRC="videolist.jsp" OLDID="1485" RELATED="1"></script>’

 

解决办法:<script language="javascript" src="http://www.hechuan.gov.cn/video/videolist.jsp"  ignoreapd="1"></script>’

加入了ignoreapd="1"属性,让WCM这段不进行解析。

posted @ 2009-02-01 15:49 田了你 阅读(95) 评论(0) 编辑

2008年11月27日 #

摘要: 关键字: 锚点 平滑 定位对于定位到一个锚点,最常见的方法就是在url后面加上“#和锚点的name值”,下面先介绍一种如何采用Javascript定位锚点的方法:window.location.hash="anchorname"比如一个锚点:<a name="anchor1"></a>那么采用window.location.hash="anchor1...阅读全文
posted @ 2008-11-27 16:43 田了你 阅读(269) 评论(1) 编辑

2008年11月25日 #

摘要: 1.昨天处理了一个问题。问题描述:WCMV6 数据(wcmdocument表)导到 SEERVER6.0里进行全文检索,通过网关进行同步数据,但出现了标题字段检索不到的问题。解决办法:由于网关设置的时,把doctitle字段类型改为PHRASE,这样就可以进行检索了。阅读全文
posted @ 2008-11-25 18:33 田了你 阅读(13) 评论(0) 编辑

2008年7月22日 #

摘要: 今天下午搞一个Grid翻页的东东。出现一个问题,当我点击翻页后,IE就死掉了,动不了了。找来找去,终于发现是由于RadGrid 里的一属性导致的问题。UseStaticHeaders="true"就是上面这小子```耗了我半天时间,如果需要翻页的话,就应该把UseStaticHeaders属性设置为false。问题解决。但又出现了个问题,就是如果UseStaticHeaders属性为 false的...阅读全文
posted @ 2008-07-22 16:50 田了你 阅读(315) 评论(0) 编辑

2008年7月17日 #

摘要: 很久没写blog了.最近心情极其烦躁.一切都会好起来.加油!!阅读全文
posted @ 2008-07-17 11:00 田了你 阅读(34) 评论(1) 编辑

2007年3月7日 #

摘要: 1.<button onclick="alert('aaa')"></button>2.element.onclick=function(){}3.element.onclick=new Function()4.element.attachEvent("onclick",function(){})阅读全文
posted @ 2007-03-07 14:50 田了你 阅读(2592) 评论(2) 编辑