仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 445|回复: 9
打印 上一主题 下一主题

[学习教程] JAVA网页编程之用毗连池进步Servlet会见数据库的效力 ...

[复制链接]
透明 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:19:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
C++编译的是本地码,优点是启动快,而且可以精确控制资源因此可以开发很高效的程序.缺点是编程麻烦,而且容易留下安全隐患.跨平台靠源代码在各个平台间分别编译(一处编写到处编译)servlet|会见|数据|数据库JavaServlet作为首选的服务器端数据处置手艺,正在敏捷代替CGI剧本。Servlet超出CGI的上风之一在于,不但多个哀求
能够共享公用资本,并且还能够在分歧用户哀求之间保存延续数据。本文先容一种充实发扬该特征的有用手艺,即数据库连
接池。


1、完成毗连池的意义

静态Web站点常常用数据库存储的信息天生Web页面,每个页面哀求招致一次数据库会见。毗连
数据库不但要开支必定的通信和内存资本,还必需完成用户考证、平安高低文设置这类义务,因此常常成为最为耗时的操
作。固然,实践的毗连工夫开支一成不变,但1到2秒提早并不是不罕见。假如某个基于数据库的Web使用只需创建一次初始连
接,分歧页面哀求可以共享统一毗连,就可以取得明显的功能改良。
Servlet是一个Java类。Servlet引擎(它多是Web服务软件的一部分,也多是一个自力的附加模块)在体系启动或Servlet
第一次被哀求时将该类装进Java假造机并创立它的一个实例。分歧用户哀求由统一Servlet实例的多个自力线程处置。那些要
求在分歧哀求之间延续无效的数据既能够用Servlet的实例变量来保留,也能够保留在自力的帮助对象中。
用JDBC会见数据库起首要创立与数据库之间的毗连,取得一个毗连对象(Connection),由毗连对象供应实行SQL语句的办法。
本文先容的数据库毗连池包含一个办理类DBConnectionManager,卖力供应与多个毗连池对象(DBConnectionPool类)之间
的接口。每个毗连池对象办理一组JDBC毗连对象,每个毗连对象能够被恣意数目的Servlet共享。
类DBConnectionPool供应以下功效:

1)从毗连池猎取(或创立)可用毗连。
2)把毗连前往给毗连池。
3)在体系封闭时开释一切资本,封闭一切毗连。

别的,DBConnectionPool类还可以处置有效毗连(本来挂号为可用的毗连,因为某种缘故原由不再可用,如超时,通信成绩)
,并可以限定毗连池中的毗连总数不凌驾某个预定值。
办理类DBConnectionManager用于办理多个毗连池对象,它供应以下功效:

1)装载和注册JDBC驱动程序。
2)依据在属性文件中界说的属性创立毗连池对象。
3)完成毗连池名字与实在例之间的映照。
4)跟踪客户程序对毗连池的援用,包管在最初一个客户程序停止时平安地封闭一切毗连池。

本文余下部分将具体申明这两个类,最初给出一个示例演示Servlet利用毗连池的一样平常历程。


2、详细完成

DBConnectionManager.java程序清单以下:

001importjava.io.*;
002importjava.sql.*;
003importjava.util.*;
004importjava.util.Date;
005
006/**
007*办理类DBConnectionManager撑持对一个或多个由属性文件界说的数据库毗连
008*池的会见.客户程序能够挪用getInstance()办法会见本类的独一实例.
009*/
010publicclassDBConnectionManager{
011staticprivateDBConnectionManagerinstance;//独一实例
012staticprivateintclients;
013
014privateVectordrivers=newVector();
015privatePrintWriterlog;
016privateHashtablepools=newHashtable();
017
018/**
019*前往独一实例.假如是第一次挪用此办法,则创立实例
020*
021*@returnDBConnectionManager独一实例
022*/
023staticsynchronizedpublicDBConnectionManagergetInstance(){
024if(instance==null){
025instance=newDBConnectionManager();
026}
027clients++;
028returninstance;
029}
030
031/**
032*建构函数公有以避免别的对象创立本类实例
033*/
034privateDBConnectionManager(){
035init();
036}
037
038/**
039*将毗连对象前往给由名字指定的毗连池
040*
041*@paramname在属性文件中界说的毗连池名字
042*@paramcon毗连对象
043*/
044publicvoidfreeConnection(Stringname,Connectioncon){
045DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
046if(pool!=null){
047pool.freeConnection(con);
048}
049}
050
051/**
052*取得一个可用的(余暇的)毗连.假如没有可用毗连,且已有毗连数小于最年夜毗连数
053*限定,则创立并前往新毗连
054*
055*@paramname在属性文件中界说的毗连池名字
056*@returnConnection可用毗连或null
057*/
058publicConnectiongetConnection(Stringname){
059DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
060if(pool!=null){
061returnpool.getConnection();
062}
063returnnull;
064}
065
066/**
067*取得一个可用毗连.若没有可用毗连,且已有毗连数小于最年夜毗连数限定,
068*则创立并前往新毗连.不然,在指定的工夫内守候别的线程开释毗连.
069*
070*@paramname毗连池名字
071*@paramtime以毫秒计的守候工夫
072*@returnConnection可用毗连或null
073*/
074publicConnectiongetConnection(Stringname,longtime){
075DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
076if(pool!=null){
077returnpool.getConnection(time);
078}
079returnnull;
080}
081
082/**
083*封闭一切毗连,打消驱动程序的注册
084*/
085publicsynchronizedvoidrelease(){
086//守候直到最初一个客户程序挪用
087if(--clients!=0){
088return;
089}
090
091EnumerationallPools=pools.elements();
092while(allPools.hasMoreElements()){
093DBConnectionPoolpool=(DBConnectionPool)allPools.nextElement();
094pool.release();
095}
096EnumerationallDrivers=drivers.elements();
097while(allDrivers.hasMoreElements()){
098Driverdriver=(Driver)allDrivers.nextElement();
099try{
100DriverManager.deregisterDriver(driver);
101log("打消JDBC驱动程序"+driver.getClass().getName()+"的注册");
102}
103catch(SQLExceptione){
104log(e,"没法打消以下JDBC驱动程序的注册:"+driver.getClass().getName());
105}
106}
107}
108
109/**
110*依据指定属性创立毗连池实例.
111*
112*@paramprops毗连池属性
113*/
114privatevoidcreatePools(Propertiesprops){
115EnumerationpropNames=props.propertyNames();
116while(propNames.hasMoreElements()){
117Stringname=(String)propNames.nextElement();
118if(name.endsWith(".url")){
119StringpoolName=name.substring(0,name.lastIndexOf("."));
120Stringurl=props.getProperty(poolName+".url");
121if(url==null){
122log("没无为毗连池"+poolName+"指定URL");
123continue;
124}
125Stringuser=props.getProperty(poolName+".user");
126Stringpassword=props.getProperty(poolName+".password");
127Stringmaxconn=props.getProperty(poolName+".maxconn","0");
128intmax;
129try{
130max=Integer.valueOf(maxconn).intValue();
131}
132catch(NumberFormatExceptione){
133log("毛病的最年夜毗连数限定:"+maxconn+".毗连池:"+poolName);
134max=0;
135}
136DBConnectionPoolpool=
137newDBConnectionPool(poolName,url,user,password,max);
138pools.put(poolName,pool);
139log("乐成创立毗连池"+poolName);
140}
141}
142}
143
144/**
145*读取属性完成初始化
146*/
147privatevoidinit(){
148InputStreamis=getClass().getResourceAsStream("/db.properties");
149PropertiesdbProps=newProperties();
150try{
151dbProps.load(is);
152}
153catch(Exceptione){
154System.err.println("不克不及读取属性文件."+
155"请确保db.properties在CLASSPATH指定的路径中");
156return;
157}
158StringlogFile=dbProps.getProperty("logfile","DBConnectionManager.log");
159try{
160log=newPrintWriter(newFileWriter(logFile,true),true);
161}
162catch(IOExceptione){
163System.err.println("没法翻开日记文件:"+logFile);
164log=newPrintWriter(System.err);
165}
166loadDrivers(dbProps);
167createPools(dbProps);
168}
169
170/**
171*装载和注册一切JDBC驱动程序
172*
173*@paramprops属性
174*/
175privatevoidloadDrivers(Propertiesprops){
176StringdriverClasses=props.getProperty("drivers");
177StringTokenizerst=newStringTokenizer(driverClasses);
178while(st.hasMoreElements()){
179StringdriverClassName=st.nextToken().trim();
180try{
181Driverdriver=(Driver)
182Class.forName(driverClassName).newInstance();
183DriverManager.registerDriver(driver);
184drivers.addElement(driver);
185log("乐成注册JDBC驱动程序"+driverClassName);
186}
187catch(Exceptione){
188log("没法注册JDBC驱动程序:"+
189driverClassName+",毛病:"+e);
190}
191}
192}
193
194/**
195*将文本信息写进日记文件
196*/
197privatevoidlog(Stringmsg){
198log.println(newDate()+":"+msg);
199}
200
201/**
202*将文本信息与非常写进日记文件
203*/
204privatevoidlog(Throwablee,Stringmsg){
205log.println(newDate()+":"+msg);
206e.printStackTrace(log);
207}
208
209/**
210*此外部类界说了一个毗连池.它可以依据请求创立新毗连,直到预定的最
211*年夜毗连数为止.在前往毗连给客户程序之前,它可以考证毗连的无效性.
212*/
213classDBConnectionPool{
214privateintcheckedOut;
215privateVectorfreeConnections=newVector();
216privateintmaxConn;
217privateStringname;
218privateStringpassword;
219privateStringURL;
220privateStringuser;
221
222/**
223*创立新的毗连池
224*
225*@paramname毗连池名字
226*@paramURL数据库的JDBCURL
227*@paramuser数据库帐号,或null
228*@parampassword暗码,或null
229*@parammaxConn此毗连池同意创建的最年夜毗连数
230*/
231publicDBConnectionPool(Stringname,StringURL,Stringuser,Stringpassword,
232intmaxConn){
233this.name=name;
234this.URL=URL;
235this.user=user;
236this.password=password;
237this.maxConn=maxConn;
238}
239
240/**
241*将不再利用的毗连前往给毗连池
242*
243*@paramcon客户程序开释的毗连
244*/
245publicsynchronizedvoidfreeConnection(Connectioncon){
246//将指定毗连到场到向量开端
247freeConnections.addElement(con);
248checkedOut--;
249notifyAll();
250}
251
252/**
253*从毗连池取得一个可用毗连.如没有余暇的毗连且以后毗连数小于最年夜毗连
254*数限定,则创立新毗连.如本来挂号为可用的毗连不再无效,则从向量删除之,
255*然后递回挪用本人以实验新的可用毗连.
256*/
257publicsynchronizedConnectiongetConnection(){
258Connectioncon=null;
259if(freeConnections.size()>0){
260//猎取向量中第一个可用毗连
261con=(Connection)freeConnections.firstElement();
262freeConnections.removeElementAt(0);
263try{
264if(con.isClosed()){
265log("从毗连池"+name+"删除一个有效毗连");
266//递回挪用本人,实验再次猎取可用毗连
267con=getConnection();
268}
269}
270catch(SQLExceptione){
271log("从毗连池"+name+"删除一个有效毗连");
272//递回挪用本人,实验再次猎取可用毗连
273con=getConnection();
274}
275}
276elseif(maxConn==0||checkedOut<maxConn){
277con=newConnection();
278}
279if(con!=null){
280checkedOut++;
281}
282returncon;
283}
284
285/**
286*从毗连池猎取可用毗连.能够指定客户程序可以守候的最长工夫
287*拜见前一个getConnection()办法.
288*
289*@paramtimeout以毫秒计的守候工夫限定
290*/
291publicsynchronizedConnectiongetConnection(longtimeout){
292longstartTime=newDate().getTime();
293Connectioncon;
294while((con=getConnection())==null){
295try{
296wait(timeout);
297}
298catch(InterruptedExceptione){}
299if((newDate().getTime()-startTime)>=timeout){
300//wait()前往的缘故原由是超时
301returnnull;
302}
303}
304returncon;
305}
306
307/**
308*封闭一切毗连
309*/
310publicsynchronizedvoidrelease(){
311EnumerationallConnections=freeConnections.elements();
312while(allConnections.hasMoreElements()){
313Connectioncon=(Connection)allConnections.nextElement();
314try{
315con.close();
316log("封闭毗连池"+name+"中的一个毗连");
317}
318catch(SQLExceptione){
319log(e,"没法封闭毗连池"+name+"中的毗连");
320}
321}
322freeConnections.removeAllElements();
323}
324
325/**
326*创立新的毗连
327*/
328privateConnectionnewConnection(){
329Connectioncon=null;
330try{
331if(user==null){
332con=DriverManager.getConnection(URL);
333}
334else{
335con=DriverManager.getConnection(URL,user,password);
336}
337log("毗连池"+name+"创立一个新的毗连");
338}
339catch(SQLExceptione){
340log(e,"没法创立以下URL的毗连:"+URL);
341returnnull;
342}
343returncon;
344}
345}
346}



java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大.
简单生活 该用户已被删除
沙发
发表于 2015-1-18 17:13:45 | 只看该作者
你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。
飘飘悠悠 该用户已被删除
板凳
发表于 2015-1-27 05:16:23 | 只看该作者
是一种将安全性(Security)列为第一优先考虑的语言
兰色精灵 该用户已被删除
地板
发表于 2015-2-4 22:36:33 | 只看该作者
Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)
老尸 该用户已被删除
5#
发表于 2015-2-10 22:00:02 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
愤怒的大鸟 该用户已被删除
6#
发表于 2015-2-21 22:19:12 | 只看该作者
是一种使用者不需花费很多时间学习的语言
冷月葬花魂 该用户已被删除
7#
发表于 2015-3-6 21:59:57 | 只看该作者
如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。
山那边是海 该用户已被删除
8#
发表于 2015-3-13 01:07:19 | 只看该作者
你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
因胸联盟 该用户已被删除
9#
发表于 2015-3-13 08:06:14 | 只看该作者
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
第二个灵魂 该用户已被删除
10#
发表于 2015-3-20 16:38:19 | 只看该作者
是一种简化的C++语言 是一种安全的语言,具有阻绝计算机病毒传输的功能
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-9-28 13:15

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表