大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> JSP专区 -> 用连接池提高Servlet访问数据库的效率(1)

用连接池提高Servlet访问数据库的效率(1)

时间: 2021-07-31 作者:daque

java servlet动作首要选择的效劳器端数据处置本领,正在赶快代替cgi剧本。servlet胜过cgi的上风之一在乎,不只多个乞求不妨共享公用资源,并且还不妨在各别用户乞求之间保持连接数据。正文引见一种充溢表现该特性的适用本领,即数据库贯穿池。一、实行贯穿池的意旨动静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运用贯穿池的普遍进程。二、简直实行dbconnectionmanager.java步调清单如次:001 import java.io.*;002 import java.sql.*;003 import java.util.*;004 import java.util.date;005006 /**007 * 处置类dbconnectionmanager扶助对一个或多个由属性文献设置的数据库贯穿008 * 池的考察.存户步调不妨挪用getinstance()本领考察本类的独一范例.009 */010 public class dbconnectionmanager {011 static private dbconnectionmanager instance; // 独一范例012 static private int clients;013014 private vector drivers = new vector();015 private printwriter log;016 private hashtable pools = new hashtable();017018 /**019 * 归来独一范例.即使是第一次挪用此本领,则创造范例020 *021 * @return dbconnectionmanager 独一范例022 */023 static synchronized public dbconnectionmanager getinstance() {024 if (instance == null) {025 instance = new dbconnectionmanager();026 }027 clients++;028 return instance;029 }030031 /**032 * 建构因变量独占以提防其它东西创造本类范例033 */034 private dbconnectionmanager() {035 init();036 }037038 /**039 * 将贯穿东西归来给由名字指定的贯穿池040 *041 * @param name 在属性文献中设置的贯穿池名字042 * @param con 贯穿东西043 */044 public void freeconnection(string name, connection con) {045 dbconnectionpool pool = (dbconnectionpool) pools.get(name);046 if (pool != null) {047 pool.freeconnection(con);048 }049 }050051 /**052 * 赢得一个可用的(清闲的)贯穿.即使没有可用贯穿,且已有贯穿数小于最大贯穿数053 * 控制,则创造并归来新贯穿054 *055 * @param name 在属性文献中设置的贯穿池名字056 * @return connection 可用贯穿或null057 */058 public connection getconnection(string name) {059 dbconnectionpool pool = (dbconnectionpool) pools.get(name);060 if (pool != null) {061 return pool.getconnection();062 }063 return null;064 }065066 /**067 * 赢得一个可用贯穿.若没有可用贯穿,且已有贯穿数小于最大贯穿数控制,068 * 则创造并归来新贯穿.要不,在指定的功夫内等候其它线程开释贯穿.069 *070 * @param name 贯穿池名字071 * @param time 以毫秒计的等候功夫072 * @return connection 可用贯穿或null073 */074 public connection getconnection(string name, long time) {075 dbconnectionpool pool = (dbconnectionpool) pools.get(name);076 if (pool != null) {077 return pool.getconnection(time);078 }079 return null;080 }081082 /**083 * 封闭一切贯穿,废除启动步调的备案084 */085 public synchronized void release() {086 // 等候直到结果一个存户步调挪用087 if (--clients != 0) {088 return;089 }090091 enumeration allpools = pools.elements();092 while (allpools.hasmoreelements()) {093 dbconnectionpool pool = (dbconnectionpool) allpools.nextelement();094 pool.release();095 }096 enumeration alldrivers = drivers.elements();097 while (alldrivers.hasmoreelements()) {098 driver driver = (driver) alldrivers.nextelement();099 try {100 drivermanager.deregisterdriver(driver);101 log("废除jdbc启动步调 " + driver.getclass().getname()+"的备案");102 }103 catch (sqlexception e) {104 log(e, "没辙废除下列jdbc启动步调的备案: " + driver.getclass().getname());105 }106 }107 }108109 /**110 * 按照指定属性创造贯穿池范例.111 *112 * @param props 贯穿池属性113 */114 private void createpools(properties props) {115 enumeration propnames = props.propertynames();116 while (propnames.hasmoreelements()) {117 string name = (string) propnames.nextelement();118 if (name.endswith(".url")) {119 string poolname = name.substring(0, name.lastindexof("."));120 string url = props.getproperty(poolname + ".url");121 if (url == null) {122 log("没成器贯穿池" + poolname + "指定url");123 continue;124 }125 string user = props.getproperty(poolname + ".user");126 string password = props.getproperty(poolname + ".password");127 string maxconn = props.getproperty(poolname + ".maxconn", "0");128 int max;129 try {130 max = integer.valueof(maxconn).intvalue();131 }132 catch (numberformatexception e) {133 log("缺点的最大贯穿数控制: " + maxconn + " .贯穿池: " + poolname);134 max = 0;135 }136 dbconnectionpool pool =137 new dbconnectionpool(poolname, url, user, password, max);138 pools.put(poolname, pool);139 log("胜利创造贯穿池" + poolname);140 }141 }142 }143144 /**145 * 读取属性实行初始化146 */147 private void init() {148 inputstream is = getclass().getresourceasstream("/db.properties");149 properties dbprops = new properties();150 try {151 dbprops.load(is);152 }153 catch (exception e) {154 system.err.println("不许读取属性文献. " +155 "请保证db.properties在classpath指定的路途中");156 return;157 }158 string logfile = dbprops.getproperty("logfile", "dbconnectionmanager.log");159 try {160 log = new printwriter(new filewriter(logfile, true), true);161 }162 catch (ioexception e) {163 system.err.println("没辙翻开日记文献: " + logfile);164 log = new printwriter(system.err);165 }166 loaddrivers(dbprops);167 createpools(dbprops);168 }169170 /**171 * 承载和备案一切jdbc启动步调172 *173 * @param props 属性174 */175 private void loaddrivers(properties props) {176 string driverclasses = props.getproperty("drivers");177 stringtokenizer st = new stringtokenizer(driverclasses);178 while (st.hasmoreelements()) {179 string driverclassname = st.nexttoken().trim();180 try {181 driver driver = (driver)182 class.forname(driverclassname).newinstance();183 drivermanager.registerdriver(driver);184 drivers.addelement(driver);185 log("胜利备案jdbc启动步调" + driverclassname);186 }187 catch (exception e) {188 log("没辙备案jdbc启动步调: " +189 driverclassname + ", 缺点: " + e);190 }191 }192 }193194 /**195 * 将文本消息写入日记文献196 */197 private void log(string msg) {198 log.println(new date() + ": " + msg);199 }200201 /**202 * 将文本消息与特殊写入日记文献203 */204 private void log(throwable e, string msg) {205 log.println(new date() + ": " + msg);206 e.printstacktrace(log);207 }208209 /**210 * 此里面类设置了一个贯穿池.它不妨按照诉求创造新贯穿,直到预订的最211 * 大贯穿数为止.在归来贯穿给存户步调之前,它不妨考证贯穿的灵验性.212 */213 class dbconnectionpool {214 private int checkedout;215 private vector freeconnections = new vector();216 private int maxconn;217 private string name;218 private string password;219 private string url;220 private string user;221222 /**223 * 创造新的贯穿池224 *225 * @param name 贯穿池名字226 * @param url 数据库的jdbc url227 * @param user 数据库帐号,或 null228 * @param password 暗号,或 null229 * @param maxconn 此贯穿池承诺创造的最大贯穿数230 */231 public dbconnectionpool(string name, string url, string user, string password,232 int maxconn) {233 this.name = name;234 this.url = url;235 this.user = user;236 this.password = password;237 this.maxconn = maxconn;238 }239240 /**241 * 将不复运用的贯穿归来给贯穿池242 *243 * @param con 存户步调开释的贯穿244 */245 public synchronized void freeconnection(connection con) {246 // 将指定贯穿介入到向量结束247 freeconnections.addelement(con);248 checkedout--;249 notifyall();250 }251252 /**253 * 从贯穿池赢得一个可用贯穿.如没有清闲的贯穿且暂时贯穿数小于最大贯穿254 * 数控制,则创造新贯穿.如从来备案为可用的贯穿不复灵验,则从向量简略之,255 * 而后递归挪用本人以试验新的可用贯穿.256 */257 public synchronized connection getconnection() {258 connection con = null;259 if (freeconnections.size() > 0) {260 // 获得向量中第一个可用贯穿261 con = (connection) freeconnections.firstelement();262 freeconnections.removeelementat(0);263 try {264 if (con.isclosed()) {265 log("从贯穿池" + name+"简略一个失效贯穿");266 // 递归挪用本人,试验再次获得可用贯穿267 con = getconnection();268 }269 }270 catch (sqlexception e) {271 log("从贯穿池" + name+"简略一个失效贯穿");272 // 递归挪用本人,试验再次获得可用贯穿273 con = getconnection();274 }275 }276 else if (maxconn == 0 || checkedout < maxconn) {277 con = newconnection();278 }279 if (con != null) {280 checkedout++;281 }282 return con;283 }284285 /**286 * 从贯穿池获得可用贯穿.不妨指定存户步调不妨等候的最长功夫287 * 拜见前一个getconnection()本领.288 *289 * @param timeout 以毫秒计的等候功夫控制290 */291 public synchronized connection getconnection(long timeout) {292 long starttime = new date().gettime();293 connection con;294 while ((con = getconnection()) == null) {295 try {296 wait(timeout);297 }298 catch (interruptedexception e) {}299 if ((new date().gettime() - starttime) >= timeout) {300 // wait()归来的因为是超时301 return null;302 }303 }304 return con;305 }306307 /**308 * 封闭一切贯穿309 */310 public synchronized void release() {311 enumeration allconnections = freeconnections.elements();312 while (allconnections.hasmoreelements()) {313 connection con = (connection) allconnections.nextelement();314 try {315 con.close();316 log("封闭贯穿池" + name+"中的一个贯穿");317 }318 catch (sqlexception e) {319 log(e, "没辙封闭贯穿池" + name+"中的贯穿");320 }321 }322 freeconnections.removeallelements();323 }324325 /**326 * 创造新的贯穿327 */328 private connection newconnection() {329 connection con = null;330 try {331 if (user == null) {332 con = drivermanager.getconnection(url);333 }334 else {335 con = drivermanager.getconnection(url, user, password);336 }337 log("贯穿池" + name+"创造一个新的贯穿");338 }339 catch (sqlexception e) {340 log(e, "没辙创造下列url的贯穿: " + url);341 return null;342 }343 return con;344 }345 }346 }

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.