??xml version="1.0" encoding="utf-8" standalone="yes"?>
也就是用多态来实现回调函数
public interface ICallback {
public void func();
}
public class ClassWithCallbackFunction implements ICallback{
public ClassWithCallbackFunction() {
}
public void func(){
System.out.println("cccccccccccccccccc");
}
}
public class Caller {
ICallback callback;
public void doCallback() {
callback.func();
}
public void setCallback(ICallback callback) {
this.callback = callback;
}
}
public class MainClass {
public MainClass() {
}
public static void main(String[] args) {
Caller caller = new Caller();
caller.setCallback(new ClassWithCallbackFunction() {
public void func() {
System.out.println("aaaaaaaaaa");
}
});
caller.doCallback();
}
}
现实中是把doCallback()Ҏ攑֜setCallback里调?以上是ؓ了说明回调原?br>public class Caller {
ICallback callback;
public void doCallback() {
callback.func();
}
public void setCallback(ICallback callback) {
this.callback = callback;
doCallback();
}
}
DWR(Direct Web Remoting)是一个WEBq程调用框架.利用q个框架可以让AJAX开发变得很?利用DWR可以在客L利用JavaScript直接调用服务端的JavaҎq返回值给JavaScript好像直接本地客L调用一?DWRҎJavacL动态生成JavaScrip代码).它的最新版?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">DWR0.6d许多Ҏ如:支持Dom Trees的自动配|?支持Spring(JavaScriptq程调用spring bean),更好览器支?q支持一个可选的commons-logging日记操作. 以上摘自open-openQ看了几天,实是一个非怼U的项目,它通过反射Q将java译成javascriptQ然后利用回调机ӞL实现了javascript调用Java代码?br /> 其大概开发过E如下: 1.~写业务代码Q该代码是和dwr无关的?br />2.认业务代码中哪些类、哪些方法是要由javascript直接讉K的?br />3.~写dwrlgQ对步骤2的方法进行封装?br />4.配置dwrlg?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr.xml文g中,如果有必要,配置convertQ进行java和javascriptcd互{?br />5.通过反射机制Q?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr步?的类转换成javascript代码Q提供给前台面调用?br />5.~写|页Q调用步?的javascript中的相关ҎQ间接调用服务器端的相关cȝҎQ,执行业务逻辑Q将执行l果利用回调函数q回?br />6.在回调函CQ得到执行结果后Q可以l编写业务逻辑的相关javascript代码?br /> 下面以用h册的例子Q来说明其用。(注意Q本ơ例子只是用于演C,说明DWR的用,c设计ƈ不是最优的Q?br /> 1.先介l下相关的Javac?br /> User: 用户c, public class User { //登陆IDQ主键唯一 private String id; //姓名 private String name; //口o private String password; //电子邮g private String email; //以下包含getXXX和setXXXҎ ....... } UserDAOQ实现User的数据库讉KQ这里作Z个演C,~写试代码 public class UserDAO { //存放保存的数?br /> private static Map dataMap = new HashMap(); //持久用户 public boolean save(User user) { if (dataMap.containsKey(user.getId())) return false; System.out.println("下面开始保存用?); System.out.println("idQ?+user.getId()); System.out.println("passwordQ?+user.getPassword()); System.out.println("nameQ?+user.getName()); System.out.println("emailQ?+user.getEmail()); dataMap.put(user.getId(), user); System.out.println("用户保存l束"); return true; } //查找用户 public User find(String id) { return (User)dataMap.get(id); } } DWRUserAccessQ?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">DWRlgQ提供给javascript讉K的?br /> public class DWRUserAccess { UserDAO userDAO = new UserDAO(); public boolean save(User user) { return userDAO.save(user); } public User find(String id) { return userDAO.find(id); } } 下面说明下程序执行的程 1.用户在页面上输入相关注册信息Qid、name、password、emailQ点几Z提交”按?br /> 2.javascript代码开始执行,Ҏ用户填写相关信息Q通过dwr提供的DWRUserAccess.js里save的方法,调用服务器端的DWRUserAccesscsaveҎQ将注册信息保存?br /> 3.通过DWRUserAccess.jsp里的findҎQ调用服务器端DWRUserAccessc里的findҎQ执行用户信息查找?br /> 注意Q在以上的执行过E中QDWRUserAccess是供DWR调用的,?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">DWRlgQ因此需要将DWRUserAccessc配|到dwr中?br /> 接下来讲解本?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr试环境的配|?br /> 1.新徏一个webappQ命名ؓtestApp 2.?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr.jar拯到testApp的WEB-INF的lib目录?br /> 3.~译上面的UserQUserDAOQDWRUserAccessc,攑ֈclasses目录?br /> 4.在web.xml中配|servlet,适配路径?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr目录?如下所C?br /> <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <description>Direct Web Remoter Servlet</description> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>scriptCompressed</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> 以上的配|可以拦截testApp下所有指?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr的请求,关于q个拦截器,我们会在后面介绍?br /> 5.WEB-INF下新Z?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr.xml文gQ内容如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <create creator="new" javascript="DWRUserAccess"> <param name="class" value="test.DWRUserAccess"/> </create> <convert converter="bean" match="test.User"/> </allow> </dwr> q里我们把DWRUserAccess配置Cdwr中,create元素中,creater="new"表示每调用一ơDWRUserAccessӞ需要new一个这Lc;javascript="DWRUserAccess"Q表C提供给前台面调用的javascirpt文g是DWRUserAccess.js?br /> convert元素用于数据cd转换Q即javacdjavascript之间怺转换Q因为和前台交换的是User对象Q因此需要对此用bean转换Q我们将在后面介l这个类?br /> 4.~写试的HTML面 test.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>DWR试</TITLE> <meta http-equiv=Content-Type content="text/html; charset=gb2312"> <script src="/oblog312/dwr/engine.js"></script> <script src="/oblog312/dwr/util.js"></script> <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script> </HEAD> <BODY> <B>用户注册</B><br> ------------------------------------------------ <Br> <form name="regForm"> 登陆IDQ?lt;input type="text" name="id"><br> 口 oQ?lt;input type="password" name="password"><br> 姓 名Q?lt;input type="text" name="name"><br> 电子邮gQ?lt;input type="text" name="email"><br> <input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br> </form> <br> <br><B>用户查询</B><br> ------------------------------------------------ <Br> <form name="queryForm"> 登陆IDQ?lt;input type="text" name="id"><br> <input type="button" name="submitBtn" value="提交" onclick="OnFind()"><br> </form> <br> </BODY> </HTML> <SCRIPT LANGUAGE="JavaScript"> <!-- function saveFun(data) { if (data) { alert("注册成功Q?); } else { alert("登陆ID已经存在Q?); } } function OnSave() { var userMap = {}; userMap.id = regForm.id.value; userMap.password = regForm.password.value; userMap.name = regForm.name.value; userMap.email = regForm.email.value; DWRUserAccess.save(userMap, saveFun); } function findFun(data) { if (data == null) { alert("无法扑ֈ用户Q?+queryForm.id.value); return; } alert("扑ֈ用户Q\nidQ?+data.id+"Q\npasswordQ?+data.password+"Q\nnameQ?+data.name+"Q\nemailQ?+data.email); } function OnFind() { DWRUserAccess.find(queryForm.id.value, findFun); } //--> </SCRIPT> 以下寚w面的javascriptq行解释 <script src="/oblog312/dwr/engine.js"></script> <script src="/oblog312/dwr/util.js"></script> q两个是dwr提供的,用户可以不必兛_Q只需要导入即?br /> <script src="/oblog312/dwr/interface/DWRUserAccess.js"></script> 是我们编写的DWRUserAccessc,l?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr反射后,生成的javascript代码Q它和DWRUserAccess.java是对应的Q供用户调用Q实际上我们是通过q个js文g去调用服务器端的DWRUserAccesscȝ?br /> <SCRIPT LANGUAGE="JavaScript"> <!-- function saveFun(data) { if (data) { alert("注册成功Q?); } else { alert("用户名已l存在!"); } } function OnSave() { var userMap = {}; userMap.id = regForm.id.value; userMap.password = regForm.password.value; userMap.name = regForm.name.value; userMap.email = regForm.email.value; DWRUserAccess.save(userMap, saveFun); } function findFun(data) { if (data == null) { alert("无法扑ֈ用户Q?+queryForm.id.value); return; } alert("扑ֈ用户Q\nidQ?+data.id+"Q\npasswordQ?+data.password+"Q\nnameQ?+data.name+"Q\nemailQ?+data.email); } function OnFind() { DWRUserAccess.find(queryForm.id.value, findFun); } //--> </SCRIPT> q段javascirpt代码Q我们来看下OnSave函数Q首先它构造一个mapQ将表单数据都设|到map中,然后调用 DWRUserAccess.save(userMap, saveFun)Q执行save操作。大家可以注意到Q服务器端的DWRUserAccess中的saveҎ是这LQboolean save(User user)Q其参数是一个User对象Q返回一个boolean|而客L的方法是q样的:save(userMap,saveFun)Q第一个参?userMap是javascirpt中的map对象Q在q里相当于服务器端的User对象Q在服务器端执行Ӟ会通过convert转换成User对象Q,前面我们提到dwr是利用回调函数来q回执行l果的,W二个参数saveFunx一个回调函数。在函数function saveFun(data)中,data是执行结果,q里是一个bool|非常单的Q我们通过判断data是否为真Q可以知道用户名是否重复Q用h否注册成功?br /> 看一下OnFind查找函数Q执行结果在回调函数findFun(data)中,因ؓ服务器端q回的是一个User对象Q通过convertQ将会{换成javascript的一个map对象Q?br />于是在findFun中,通过data.id、data.name、data.password、data.email我们可以L的访问到q个User对象?br /> 好了配置完毕Q启动服务器Q在目录中打入localhost/testApp/test.html?br /> 1.在“用h册”表单中Qid框中输入adminQpassword中输?23456Qname中输入chenbugQemail中输入chenbug@zj.comQ点L交按钮,弹出对话框:“注册成功”,在服务器后台可以看到信息如下Q?br /> 下面开始保存用?br />idQadmin passwordQ?23456 nameQchenbug emailQchenbug@zj.com 用户保存l束 再次点击提交按钮Q弹出对话框“登陆ID已经存在”?br /> 2.在“用h询”对话框中,输入登陆ID为adminQ点L交按钮,提示扑ֈ用户Qƈ昄相关信息Q输入admin123Q点L交按钮,提示无法扑ֈ用户?br /> xQ测试结束?br /> 后箋Q?br />1。拦截器 uk.ltd.getahead.dwr.DWRServlet 该类拦截所有指?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr目录下的hQƈ调用Processor的handlerҎq行处理Q在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我们可以看到详细的处理过E?br />if (pathInfo.length() == 0 || pathInfo.equals(HtmlConstants.PATH_ROOT) || pathInfo.equals(req.getContextPath())) { resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX); } else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX)) { index.handle(req, resp); } else if (pathInfo.startsWith(HtmlConstants.PATH_TEST)) { test.handle(req, resp); } else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE)) { iface.handle(req, resp); } else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC)) { exec.handle(req, resp); } else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE)) { file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS); } else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL)) { file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS); } else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED)) { file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS); } else { log.warn("Page not found (" + pathInfo + "). In debug/test mode try viewing /[WEB-APP]/dwr/"); //$NON-NLS-1$ //$NON-NLS-2$ resp.sendError(HttpServletResponse.SC_NOT_FOUND); } 通过判断requesth的servlet路径Q进行处理,大家可以自己d看,q里不详l讨论?br /> 2.bean转换器,<convert converter="bean" match="test.User"/> ?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr.jar解压~,在\径uk\ltd\getahead\dwr下可以看?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">dwr.xmlQ这里配|了pȝ默认的一些{换器Q?br /><converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>x刚才用到Usercȝ转换器,q入代码我们来看看它是如何在javascript和java间进行{换的?br /> 打开BeanConverter代码Q定位到函数 public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws ConversionException xjavascript对象转换成java对象的,其中 paramType即ClasscdQ在上面的例子中是test.UserQ?br />InboundVariable ivQ是传入的|通过iv.getValue可以得到传入的javascriptg InboundContext inctxQ是入口参数上下文,用于保存转换的后java对象?br /> 因ؓ前台传入的是一个javascript的mapcdQ而map肯定是以{开始和以}l束的,于是在这个函C开始进行了判断 if (!value.startsWith(ConversionConstants.INBOUND_MAP_START)) { throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$ } if (!value.endsWith(ConversionConstants.INBOUND_MAP_END)) { throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$ } javascript中,map里各个项是用逗号q接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每个项的键值对是用冒号q接的, 在convertInbound函数的接下来的处理中Q即是通过分析map字串Q通过paramType构造java实例Q即Userc)Q然后通过反射Q将q些键值对讄到java实例中,q返回?br />q样完成了javascript到java的{换?br /> 另一个函?br />public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException xjava对象转换为javascript对象Q其实是声明和赋D句)?br />Object data Q是待{换的java对象 String varnameQ是javascript中的该对象的变量?br />OutboundContext outctxQ传出参C下文Q用于保存{换后的javascript?br /> StringBuffer buffer = new StringBuffer(); buffer.append("var "); //$NON-NLS-1$ buffer.append(varname); buffer.append("={};"); //$NON-NLS-1$ q里声明了mapcd的变量?br /> 即下来来的代码即是通过反射q行变量赋|如下 buffer.append(varname); buffer.append('.'); buffer.append(name); buffer.append('='); buffer.append(nested.getAssignCode()); buffer.append(';'); 大家可以自己d看更多的代码?br /> 3.dwr本n提供了一个测试环境,大家在配|完后,可以在IE中输入地址http://localhost/testApp/dwr/index.htmlQ看到配|的?b style="COLOR: black; BACKGROUND-COLOR: rgb(255,255,102)">DWRlgQƈq行相关试?br /> testApp下蝲地址 http://waplife.cn/testApp.rar |
public abstract class Benchmark
{
/**
* 下面操作是我们希望在子类中完?br /> */
public abstract void benchmark();
/**
* 重复执行benchmarkơ数
*/
public final long repeat (int count) {
if (count <= 0)
return 0;
else {
long startTime = System.currentTimeMillis();
for (int i = 0; i < count; i++)
benchmark();
long stopTime = System.currentTimeMillis();
return stopTime - startTime;
}
}
}
public class MethodBenchmark extends Benchmark
{
/**
* 真正定义benchmark内容
*/
public void benchmark() {
for (int i = 0; i < Integer.MAX_VALUE; i++){
System.out.printtln("i="+i);
}
}
}
也许你以前还疑惑抽象cL什么用,现在你应该彻底明白了? 至于q样做的好处,很显然啊,扩展性强,以后Benchmark内容变化,我只要再做一个承子cd可以,不必修改其他应用代码.
![]() |
abstract class和interface是Java语言中对于抽象类定义q行支持的两U机Ӟ正是׃q两U机制的存在Q才赋予了Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的怼性,甚至可以怺替换Q因此很多开发者在q行抽象cd义时对于abstract class和interface的选择昑־比较随意。其实,两者之间还是有很大的区别的Q对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意囄理解是否正确、合理。本文将对它们之间的区别q行一番剖析,试图l开发者提供一个在二者之间进行选择的依据?/blockquote> |
![]() |
析Java语言中的内部c?/b> | ||
autumn_thermal 转脓 (参与分:47178Q专家分Q?441) 发表Q?006-06-22 12:32 版本Q?.0 阅读Q?b>207? |
析Java语言中的内部c?br />作者:morgan83 来自Qcsdn 提vJava内部c(Inner ClassQ可能很多h不太熟悉Q实际上cM的概念在C++里也有,那就是嵌套类QNested ClassQ,关于q两者的区别与联p,在下文中会有Ҏ。内部类从表面上看,是在类中又定义了一个类Q下文会看到Q内部类可以在很多地方定义)Q而实际上q没有那么简单,乍看上去内部cM乎有些多余,它的用处对于初学者来说可能ƈ不是那么显著Q但是随着对它的深入了解,你会发现Java的设计者在内部cn上的是用心良苦。学会用内部类Q是掌握Java高~程的一部分Q它可以让你更优雅地设计你的E序l构。下面从以下几个斚w来介l: W一ơ见?br /> public interface Contents { int value(); } public interface Destination { String readLabel(); } public class Goods { private class Content implements Contents { private int i = 11; public int value() { return i; } } protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } } class TestGoods { public static void main(String[] args) { Goods p = new Goods(); Contents c = p.cont(); Destination d = p.dest("Beijing"); } } 在这个例子里cContent和GDestination被定义在了类Goods内部Qƈ且分别有着protected和private修饰W来控制讉KU别。Content代表着Goods的内容,而GDestination代表着Goods的目的地。它们分别实C两个接口Content和Destination。在后面的mainҎ里,直接用 Contents c和Destination dq行操作Q你甚至q这两个内部cȝ名字都没有看见!q样Q内部类的第一个好处就体现出来??隐藏你不惌别h知道的操作,也即装性。?br /> 同时Q我们也发现了在外部cM用范围之外得到内部类对象的第一个方法,那就是利用其外部cȝҎ创徏q返回。上例中的cont()和dest()Ҏ是q么做的。那么还有没有别的方法呢Q当然有Q其语法格式如下Q?br /> outerObject=new outerClass(Constructor Parameters); outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters); 注意在创建非静态内部类对象Ӟ一定要先创v相应的外部类对象。至于原因,也就引出了我们下一个话??非静态内部类对象有着指向其外部类对象的引用,对刚才的例子E作修改Q?br /> public class Goods { private valueRate=2; private class Content implements Contents { private int i = 11*valueRate; public int value() { return i; } } protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } } 修改的部分用蓝色昄了。在q里我们lGoodscd加了一个private成员变量valueRateQ意义是货物的h值系敎ͼ在内部类Content的方法value()计算价值时把它乘上。我们发玎ͼvalue()可以讉KvalueRateQ这也是内部cȝW二个好??一个内部类对象可以讉K创徏它的外部cd象的内容Q甚臛_括私有变量!q是一个非常有用的Ҏ,为我们在设计时提供了更多的思\和捷径。要惛_现这个功能,内部cd象就必须有指向外部类对象的引用。Java~译器在创徏内部cd象时Q隐式的把其外部cd象的引用也传了进dƈ一直保存着。这样就使得内部cd象始l可以访问其外部cd象,同时q也是ؓ什么在外部cM用范围之外向要创建内部类对象必须先创建其外部cd象的原因?br /> 有h会问Q如果内部类里的一个成员变量与外部cȝ一个成员变量同名,也即外部cȝ同名成员变量被屏蔽了Q怎么办?没事QJava里用如下格式表达外部cȝ引用Q?br /> outerClass.this 有了它,我们׃怕这U屏蔽的情况了?br /> 静态内部类 和普通的cMP内部cM可以有静态的。不q和非静态内部类相比Q区别就在于静态内部类没有了指向外部的引用。这实际上和C++中的嵌套cd相像了,Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用这一点上Q当然从设计的角度以及以它一些细节来讲还有区别?br /> 除此之外Q在M非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类Q内部类的嵌套可以不止一层)。不q静态内部类中却可以拥有q一切。这也算是两者的W二个区别吧?br /> 局部内部类 是的QJava内部cM可以是局部的Q它可以定义在一个方法甚至一个代码块之内?br /> public class Goods1 { public Destination dest(String s) { class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } return new GDestination(s); } public static void main(String[] args) { Goods1 g= new Goods1(); Destination d = g.dest("Beijing"); } } 上面是q样一个例子。在Ҏdest中我们定义了一个内部类Q最后由q个Ҏq回q个内部cȝ对象。如果我们在用一个内部类的时候仅需要创建它的一个对象ƈ创给外部Q就可以q样做。当Ӟ定义在方法中的内部类可以使设计多样化Q用途绝不仅仅在q一炏V?br /> 下面有一个更怪的例子Q?br /> public class Goods2{ private void internalTracking(boolean b) { if(b) { class TrackingSlip { private String id; TrackingSlip(String s) { id = s; } String getSlip() { return id; } } TrackingSlip ts = new TrackingSlip("slip"); String s = ts.getSlip(); } } public void track() { internalTracking(true); } public static void main(String[] args) { Goods2 g= new Goods2(); g.track(); } } 你不能在if之外创徏q个内部cȝ对象Q因已经出了它的作用域。不q在~译的时候,内部cTrackingSlip和其他类一样同时被~译Q只不过它由它自q作用域,出了这个范围就无效Q除此之外它和其他内部类q没有区别?br /> 匿名内部c?br /> java的匿名内部类的语法规则看上去有些古怪,不过如同匿名数组一P当你只需要创Z个类的对象而且用不上它的名字时Q用内部类可以使代码看上去z清楚。它的语法规则是q样的: new interfacename(){......}; 或 new superclassname(){......}; 下面接着前面l箋举例子: public class Goods3 { public Contents cont(){ return new Contents(){ private int i = 11; public int value() { return i; } }; } } q里Ҏcont()使用匿名内部cȝ接返回了一个实C接口Contents的类的对象,看上ȝ十分简z?br /> 在java的事件处理的匿名适配器中Q匿名内部类被大量的使用。例如在惛_闭窗口时加上q样一句代码: frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); 有一炚w要注意的是,匿名内部cȝ于没有名字,所以它没有构造函敎ͼ但是如果q个匿名内部cȝ承了一个只含有带参数构造函数的父类Q创建它的时候必d上这些参敎ͼq在实现的过E中使用super关键字调用相应的内容Q。如果你惌初始化它的成员变量,有下面几U方法: 如果是在一个方法的匿名内部c,可以利用q个Ҏ传进你想要的参数Q不q记住,q些参数必须被声明ؓfinal。?br /> 匿名内部类攚w成有名字的局部内部类Q这样它可以拥有构造函C。?br /> 在这个匿名内部类中用初始化代码块。?br /> Z么需要内部类Q?br /> java内部cL什么好处?Z么需要内部类Q?br /> 首先举一个简单的例子Q如果你惛_C个接口,但是q个接口中的一个方法和你构想的q个cM的一个方法的名称Q参数相同,你应该怎么办?q时候,你可以徏一个内部类实现q个接口。由于内部类对外部类的所有内定w是可讉K的,所以这样做可以完成所有你直接实现q个接口的功能?br /> 不过你可能要质疑Q更改一下方法的不就行了吗? 的确Q以此作计内部类的理由,实在没有说服力?br /> 真正的原因是q样的,java中的内部cd接口加在一P可以的解军_被C++E序员抱怨java中存在的一个问??没有多ѝ实际上QC++的多l承设计h很复杂,而java通过内部cd上接口,可以很好的实现多l承的效果?br /> |
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>zx0050e01</ejb-name>
<home>jp.co.sri.tyresv.zensya.service.zx.zx0050.zx0050e01.Zx0050E01Home</home>
<remote>jp.co.sri.tyresv.zensya.service.zx.zx0050.zx0050e01.Zx0050E01</remote>
<ejb-class>jp.co.sri.tyresv.zensya.service.zx.zx0050.zx0050e01.Zx0050E01Bean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<env-entry>
<description></description>
<env-entry-name>zensyaDbConnection</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>ome.DbUrl2</env-entry-value>
</env-entry>
<env-entry>
<description></description>
<env-entry-name>zensyaDbUser</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>ome.DbUser2</env-entry-value>
</env-entry>
<env-entry>
<description></description>
<env-entry-name>zensyaDbPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>ome.DbPassword2</env-entry-value>
</env-entry>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>zx0050e01</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
weblogic-ejb-jar.xml:::::::::::::::
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN' 'http://www.bea.com/servers/wls600/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>zx0050e01</ejb-name>
<jndi-name>jp.co.sri.tyresv.zensya.service.zx.zx0050.zx0050e01</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
////////////////////////////
D:\jar\Zx0050E01\jp\co\sri\tyresv\zensya\business\zx\zx0050\zx0050e01\BizZx0050E01.class
/////////////////////
D:\jar\Zx0050E01\jp\co\sri\tyresv\zensya\service\zx\zx0050\zx0050e01\Zx0050E01.class,Zx0050E01Bean.class,Zx0050E01D01$1.class,Zx0050E01D01.class,Zx0050E01D02.class,Zx0050E01Home.class,Zx0050E01I01.class
JDBCq接MySQL
加蝲及注?/span>JDBC驱动E序
Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.jdbc.Driver").newInstance();
JDBC URL 定义驱动E序与数据源之间的连?/span>
标准语法Q?/p>
<protocolQ主要通讯协议Q?/span>>:<subprotocolQ次要通讯协议Q即驱动E序名称Q?/span>>:<data source identifierQ数据源Q?/span>>
MySQL?/span>JDBC URL格式Q?/span>
jdbc:mysql//[hostname][:port]/[dbname][?param1=value1][¶m2=value2]?
CZQ?/span>jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password
常见参数Q?/p>
user 用户?/span>
password 密码
autoReconnect 联机p|Q是否重新联机(true/falseQ?/span>
maxReconnect 试重新联机ơ数
initialTimeout 试重新联机间隔
maxRows 传回最大行?/span>
useUnicode 是否使用Unicode字体~码Q?/span>true/falseQ?/span>
characterEncoding 何种~码Q?/span>GB2312/UTF-8/?/span>Q?/span>
relaxAutocommit 是否自动提交Q?/span>true/falseQ?/span>
capitalizeTypeNames 数据定义的名UC大写表示
建立q接对象
String url="jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";
Connection con = DriverManager.getConnection(url);
建立SQL陈述式对象(Statement ObjectQ?/span>
Statement stmt = con.createStatement()Q?/span>
执行SQL语句
executeQuery()
String query = "select * from test";
ResultSet rs=stmt.executeQuery(query);
l果?/span>ResultSet
while(rs.next())
{rs.getString(1);rs.getInt(2);}
executeUpdate()
String upd="insert into test (id,name) values(1001,xuzhaori)";
int con=stmt.executeUpdate(upd);
execute()
CZQ?/p>
try
{
}
catch(SQLException sqle)
{
}
finally
{
}
Javacd?/span>SQLcd技术手?/span>P421
PreparedStatementQ预~语句)
PreparedStatement stmt = conn.prepareStatement("insert into test(id,name)values(?,?)");
stmt.setInt(1,id);
stmt.setString(2,name);
注:一旦设定语句的参数值后Q就可以多次执行改语句,直到调用clearParametersQ)Ҏ他清除为止
CallableStatementQ预储程序)技术手?/span>P430
JDBC2.0使用
ResultSet对象中的光标上下自由Ud
Statement stmt = con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs=stmt.executeQuery("select * from test");
public Statement createStatement(int resultSetType,int resultSetConcuttency) throws SQLException
resultSetType
TYPE_FORWARD_ONLY 只能使用nextQ)Ҏ?/span>
TYPE_SCROLL_SENSITIVE 可以上下UdQ可以取得改变后的倹{?/span>
TYPE_SCROLL_INSENSITIVE 可以上下Ud?/span>
resultSetConcuttency
CONCUR_READ_ONLY 只读
CONCUR_UPDATABLE ResultSet对象可以执行数据库的新增、修攏V和U除
直接使用ResultSet对象执行更新数据
新增数据
Statement stmtQ?/span>con.createStatementQ?/span>ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLEQ?/span>;
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.moveToInsertRow();
uprs.updateInt(1,1001);
uprs.updateString(2,"许召?/span>");
uprs.insertRow;
更新数据
Statement stmtQ?/span>con.createStatementQ?/span>ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLEQ?/span>;
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.last();
uprs.updateString("name","xuzhaori");
uprs.updateRow;
删除数据
Statement stmtQ?/span>con.createStatementQ?/span>ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLEQ?/span>;
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.absolute(4);
uprs.deleteRow();
批处?/p>
con.setAutoCommit(false); 关闭自动认可模式
Statement stmt=con.createStatement();
int[] rows;
stmt.addBatch("insert into test values(1001,xuzhaori)");
stmt.addBatch("insert into test values(1002,xuyalin)");
rows=stmt.executeBatch();
con.commit(); 没有M错误Q执行批处理stmt.executeBatch();
JNDI-数据源(Data SourceQ与q接池(Connection PoolQ?/span>
Tomcat?/span>JDBC数据源设|?/span> 技术手?/span>P439
q接池工PProxool Var 0.8.3 技术手?/span>P446
讄web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--<?xml version="1.0" encoding="GB2312"?>-->
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
?
<servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
<init-param>
<param-name>propertyFile</param-name>
<param-value>WEB-INF/classes/Proxool.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
后端l计端口d下列
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/Admin</url-pattern>
</servlet-mapping>
?
</web-app>
配置Proxool.properties
jdbc-0.proxool.alias=JSPBook
jdbc-0.proxool.driver-class=com.mysql.jdbc.Driver
jdbc-0.proxool.driver-url=jdbc:mysql://localhost:3306/sample_db?user=root&password=browser&useUnicode=true&characterEncoding=UTF-8
jdbc-0.proxool.maximum-connection-count=10
jdbc-0.proxool.prototype-count=4
jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
jdbc-0.proxool.verbose=true
jdbc-0.proxool.statistics=10s,1m,1d 后端l计接口d此行
jdbc-0.proxool.statistics-log-level=DEBUG
使用Proxoolq接?/span>
Connectioncon = DriverManager.getConnection("proxool.JSPBook");
Statementstmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT * FROM employee";
ResultSetrs = stmt.executeQuery(query);
操作pȝ装入jvm是通过jdk中java.exe来完?通过下面4步来完成jvm环境.
1.创徏jvm装蝲环境和配|?br />2.装蝲jvm.dll
3.初始化jvm.dllq挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装蝲q处理classcR?br />
在我们运行和调试javaE序的时?l常会提C个jvm的概?jvm是javaE序q行的环?但是他同时一个操作系l的一个应用程序一个进E?因此他也有他自己的运行的生命周期,也有自己的代码和数据I间.
首先来说一下jdkq个东西,不管你是初学者还是高?是j2eeE序员还是j2seE序?jdkL在帮我们做一些事?我们在了解java之前首先大师们会l我们提供说jdkq个东西.它在java整个体系中充当着什么角色呢?我很惊叹sun大师们设计天?能把一个如此完整的体系l构化的如此完美.jdk在这个体pM充当一个生产加工中?产生所有的数据输出,是所有指令和战略的执行中?本n它提供了java的完整方?可以开发目前java能支持的所有应用和pȝE序.q里说一个问?大家会问,那ؓ什么还有j2me,j2eeq些东西,q两个东西目的很?分别用来化各自领域内的开发和构徏q程.jdk除了jvm之外,q有一些核心的API,集成API,用户工具,开发技?开发工具和API{组?br />好了,废话说了那么?来点于主题相关的东西?jvm在整个jdk中处于最底层,负责于操作系l的交互,用来屏蔽操作pȝ环境,提供一个完整的javaq行环境,因此也就虚拟计算? 操作pȝ装入jvm是通过jdk中java.exe来完?通过下面4步来完成jvm环境.
1.创徏jvm装蝲环境和配|?br />2.装蝲jvm.dll
3.初始化jvm.dllq挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装蝲q处理classcR?br />一Qjvm装入环境Qjvm提供的方式是操作pȝ的动态连接文Ӟ既然是文仉׃个装入\径的问题Qjava是怎么找这个\径的呢?当你在调用java test的时候,操作pȝ会在path下在你的java.exeE序Qjava.exe通过下面一个过E来定jvm的\径和相关的参数配|了Q下面基于windows的实现的分析Q?br /> 首先查找jre路径Qjava是通过GetApplicationHome api来获得当前的java.exel对路径Qc:\j2sdk1.4.2_09\bin\java.exe,那么它会截取到绝对\径c:\j2sdk1.4.2_09\Q判断c:\j2sdk1.4.2_09\bin\java.dll文g是否存在Q如果存在就把c:\j2sdk1.4.2_09\作ؓjre路径Q如果不存在则判断c:\j2sdk1.4.2_09\jre\bin\java.dll是否存在Q如果存在这c:\j2sdk1.4.2_09\jre作ؓjre路径Q如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\“当前JRE版本号”\JavaHome的\径ؓjre路径?br /> 然后装蝲jvm.cfg文gJRE路径+\lib+\ARCHQCPU构架Q?\jvm.cfgARCHQCPU构架Q的判断是通过java_md.c中GetArch函数判断的,该函Cwindowsq_只有两种情况QWIN64的‘ia64’,其他情况都ؓ‘i386’。以我的ZQC:\j2sdk1.4.2_09\jre\lib\i386\jvm.cfg.主要的内容如下:
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
在我们的jdk目录中jre\bin\server和jre\bin\client都有jvm.dll文g存在Q而java正是通过jvm.cfg配置文g来管理这些不同版本的jvm.dll的.通过文g我们可以定义目前jdk中支持那些jvm,前面部分QclientQ是jvm名称Q后面是参数QKNOWN表示jvm存在QALIASED_TO表示l别的jvm取一个别名,WARN表示不存在时找一个jvm替代QERROR表示不存在抛出异常.在运行java XXX是,java.exe会通过CheckJvmType来检查当前的jvmcdQjava可以通过两种参数的方式来指定具体的jvmcdQ一U按照jvm.cfg文g中的jvm名称指定Q第二种Ҏ是直接指定,它们执行的方法分别是“java -J
最后获得jvm.dll的\径,JRE路径+\bin+\jvmcd字符?\jvm.dll是jvm的文件\径了Q但是如果在调用javaE序时用-XXaltjvm=参数指定的\径path,q接用path+\jvm.dll文g做ؓjvm.dll的文件\径.
二:装蝲jvm.dll
通过W一步已l找Cjvm的\径,java通过LoadJavaVM来装入jvm.dll文gQ装入工作很单就是调用windows API函数Q?br />LoadLibrary装蝲jvm.dll动态连接库Q然后把jvm.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。jvm.dll的装载工作宣告完成?br /> 三:初始化jvmQ获得本地调用接口,q样可以在java中调用jvm的函CQ调用InvocationFunctionsQ?gt;CreateJavaVM也就是jvm中JNI_CreateJavaVMҎ获得JNIEnvl构的实例.
四:q行javaE序Q?br />javaE序有两U方式一U是jar包,一U是class. q行jar,java -jar XXX.jarq行的时候,java.exe调用GetMainClassName函数Q该函数先获得JNIEnv实例然后调用javacjava.util.jar.JarFileJNIEnv中方法getManifest()q从q回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文gQMETA-INF/MANIFEST.MF指定的Main-Class的主cd作ؓq行的主cR之后main函数会调用java.c中LoadClassҎ装蝲该主c(使用JNIEnv实例的FindClassQ。main函数直接调用java.c中LoadClassҎ装蝲该类。如果是执行classҎ。main函数直接调用java.c中LoadClassҎ装蝲该类?/jvmcd名称>
然后main函数调用JNIEnv实例的GetStaticMethodIDҎ查找装蝲的classȝ?br />“public static void main(String[] args)”方法,q判断该Ҏ是否为publicҎQ然后调用JNIEnv实例?br />CallStaticVoidMethodҎ调用该javacȝmainҎ
JSP取得在WEB.XML中定义的参数 | ||
| ||
|
weblogic的jsp问题解决Ҏ | ||
littleboys 原创 (参与分:47498Q专家分Q?30) 发表Q?002-08-27 19:26 版本Q?.0 阅读Q?B>16714? |
在做目的时候,jsp在运行的时候出C一些问题,现将我的问题解决Ҏ做一个小l,供以后作目的参考?BR> 问题1Q?BR>weblogic 的数据库q接数目在程序运行中不断增长Q最后连接数目超q最大数Q导致weblogic服务关闭 原因Q?BR>在操作完数据库后Q没有关闭数据库q接Q或者是q回l果集(ResultsetQ,而无法在jsp中关闭数据库q接?BR>解决ҎQ?BR>1Q?nbsp; 在操作完数据库要关闭数据库连接?BR>2Q?nbsp; 量不要q回l果集Resultset, 可以q回VectorQ一个字D)、HashtableQ多个字D)Q这样可以在javabean中关闭数据库?BR>3Q?nbsp; 如果javabean中返回的是结果集QResultsetQ,也可以在javaBean中写一个connectDBQ连接数据库Q、closeDB(关闭数据?的方法,然后jsp里面调用connectDBQ)Q徏立数据库q接Q同时就可以Ҏ据库q行操作了,操作数据库完毕,可以通过closeDB() 来关闭数据库?BR>使用W二U方?BR>问题2Q?BR>在运行某一个jsp E序的时候,weblogic 的内存陡然增长,而且居高不下。最l导致weblogic 内存不Q甚臛_机?BR>原因Q?BR>q度使用内存?BR>解决ҎQ?BR>1Q?nbsp; ׃数据量比较大Q在对字W串q行操作的时候,使用 + q行字符串连接,?BR> 怿大家对String都非常熟悉,我们也经常要用它来做字符串的q接什么的Q例如: String a =b+c file://b,c 都是String 但是在实际的~译中却是这P String a=new StringBuffer().append(b).append(c).toString() 昄,在一个简单的语句中却意外的多生成?个对象: .StringBuffer() .toStringq回的一个String 我们比较一下这两段E序的性能Q?BR>E序片断一Q?BR>StringBuffer s=new StringBuffer(); long start = System.currentTimeMillis(); for (int i=0;i<10000;i++){ s1+="a"; } long stop = System.currentTimeMillis(); System.out.println(stop-start); E序片断二: StringBuffer s=new StringBuffer(10000);// long start=System.currentTimeMillis(); for (int i=0;i<10000;i++){ s.append("a"); } long stop=System.currentTimeMillis(); System.out.println(stop-start); 比较一下结果,差距很明显?BR>至于Z么String的连接这么做Q因为String无法直接改变光度,而必采用StringBuffer的用法?BR>因此使用StringBuffer 的append Ҏ来进行字W串相连?BR>2Q?nbsp; 在解册个问题的时候,我也试使用上面的方法,效果q不是很明显(消耗内存上)。后来在昄大量数据的时候,避免字符串相q的步骤Q而直接用out.println(),直接输出?BR>问题3QJavaq不LE序占用q多的内?当对象向堆所h的内存不x,垃圾攉?Garbage Collector)׃自动启动,释放那些引用Cؓ零的对象所占用的内存,Java也不会自动释放无用的对象的引?如果E序忘记释放指向对象的引?则程序运行时的内存随着旉的推U而增?发生所谓内存泄?memory leaks)Q创建对象不但消耗CPU的时间和内存,同时,为释攑֯象内存JVM需不停地启动垃圾收集器(Garbage Collector),q也会消耗大量的CPU旉?BR> 解决ҎQ?nbsp;׃在运行一D|间jspE序后,weblogic 的内存会有一个缓慢的增长Q这样也会导致内存溢出,Z避免qȝ象的出现Q最l的解决Ҏ是: ~写一个servletE序Q在启动服务器的时候,启动一个这个servletQ每?0分钟q行在服务器端运行一ơ,来定时回收内存?BR> 问题4Q?BR>log文g里面的调试信息没有注释去掉?BR> 解决ҎQ?BR>在程序通过后,量把调试的信息注释L?BR>同时在捕捉错误的时候要写明E序名称Q方便查找,q一点做的还不够?BR>最好能写一个记录log的方法,以便E序调用?BR>问题5 改善性能Q提高速度?BR>具体实例Q?BR> 我们再来看一个有关Vectorcȝ代码片段Q?BR>for(int I=0; I<v.size(); I++) { System.out.println( v.get(I).getClass().toString()); } 如果v包含100,000个元素,q个代码片段调用v.size()Ҏ100,000ơ。虽然sizeҎ是一个简单的ҎQ但它仍旧需要一ơ方法调用的开销Q至JVM需要ؓ它配|以及清除堆栈环境。在q里Qfor循环内部的代码不会以M方式修改Vectorcd对象v的大,因此上面的代码最好改写成下面q种形式Q?BR>int size = v.size(); for(int I=0; I<size; I++) { System.out.println( v.get(I).getClass().toString()); } 虽然q是一个简单的改动Q但它仍旧赢得了性能。毕竟,每一个CPU周期都是宝贵的?BR>问题 6Q?BR>?nbsp;jsp 文g里面 不要?nbsp;<%@ page import="java.lang.*" %> 因ؓjava 不需要引入此包就可以引用里面的类文g?BR> 问题7Q?BR>使用vector+hashtable 一ơ返回查询结果resulset. 解决ҎQ?nbsp;记录集:一条记录放C个hashtable里面Q然后把它再 d到vector里面Q@环记录下l果集,q回vector 具体见后面的java文g的部分代码(不包扩数据库的连接和关闭Q?BR> package zjdx.bean.common; /******************************************** ***** Title: hashtable_vector_rs ***** Description: 数据昄 ***** Copyright: Copyright (c) 2002 ***** Company: DHC ***** author: wangyl ***** version: 1.0 ***** 说明Q?BR> ***** 记录集:一条记录用攑ֈ一个hashtable里面Q然后把它再 攑ֈvector里面Q@环记录下l果集,q回vector *********************************************/ import java.io.*; import java.sql.*; import java.util.*; import java.text.*; public class hashtable_vector_rs { /*----------------------------------------------------------------*/ /* 函数名称Q?nbsp;getMultiRowInfo /* 功能描述Q?nbsp;q回记录集,攑ֈHashtable里面 /* 参数Q?nbsp; sql 语句,字段个数 /* q回? 成功---htable, p|---null /*----------------------------------------------------------------*/ public Vector ListResult(String sqlStatement,int num) { Vector ListRs=new Vector(); try { connectDB(); rs=stmt.executeQuery(sqlStatement); //判断字段数据cd //date?nbsp;q回 93 //int?nbsp;q回 2,4 //bigint?nbsp;q回 3 //String?nbsp;q回 12 //(char ?q回 1 int t = -1; rsmd = rs.getMetaData(); int ColumnCount=0; if(num>0) ColumnCount = num; else ColumnCount = rsmd.getColumnCount(); while(rs.next()) { Hashtable htable =new Hashtable(); for (int i = 1; i <= ColumnCount; i++) { t=rsmd.getColumnType(i); System.out.println("i="+i+",t="+t+"name="+rsmd.getColumnName(i)); if(t==12||t==1||t==3) { if(rs.getString(i)==null|| rs.getString(i).equals("")) htable.put(rsmd.getColumnName(i),""); else htable.put(rsmd.getColumnName(i),rs.getString(i)); } else if(t==93) { htable.put(rsmd.getColumnName(i),rs.getDate(i).toString()); } else if(t==2||t==4) { htable.put(rsmd.getColumnName(i),Integer.toString(rs.getInt(i))); } } ListRs.add(htable); }//e return ListRs; } catch(Exception listError) { System.out.println("数据库操作失败!"+listError); return null; } finally { try { closeDB(); } catch(Exception closeErr) { System.out.println("关闭数据库出错:"+closeErr); } } } } 问题8: jsp的程序也有设计的不够合理的地?BR> 例如Q选择一个下拉框Q提交一ơ,列出所选的数据Q选择另外一个下拉框再次提交Q再ơ列出所选的数据?BR>解决ҎQ?BR> 量一ơ把条g选择完毕Q然后列出所选择的数据,q且在数据多的时候,量使用页Q减运行时间?BR> 问题9Q性能优化Q尽量用PreparedStatement 解决ҎQ?BR>PreparedStatement 对象和用的普通的 Statement 对象有两点不同?BR>W一Q?nbsp; 它们是ؓ了性能更快而由 JDBC 驱动E序或数据库~译Q预~译Q的?BR>W二Q?nbsp; 它们接受一个或多个动态输入参敎ͼUCؓ IN 参数。这两点?nbsp;PreparedStatement 对象适用于重复的 SQL 操作Q其中操作基本上都是一LQ只有微的差异Q如数据载入Q。要?nbsp;SQL 语句在用前预备好,?nbsp;PreparedStatement 对象创徏时必d SQL 传送到 JDBC 驱动E序Q而不是在其执行时才传送?nbsp; IN 参数?nbsp;SQL String 中的 ? 占位W表C。在 PreparedStatement 能够成功地执行前Q还必须调用 PreparedStatement 对象?nbsp;setXXX() Ҏ来设|?nbsp;IN 参数Q在q里 XXX 被设|的参数的数据类型所替换。因而,要将W一?nbsp;IN 参数讄为整数?nbsp;100Q您应该调用 setInt(1, 100)。同样地Q要第二个 IN 参数讄为字W串值“rjb”,您应该调?nbsp;setString(2, "rjb")。最后一ҎQ设|好的参数值在讄Z个新的|或用 clearParameters() 昑ּ地清除之前会保持不变。这很重要,因ؓ PreparedStatement 可以被多ơ执行;如果您不注意的话Q就会让您的数据库充满无用数据?BR>问题10 Q?BR> 1、我把包含SQLBridge 的java文g改了一遍,?2个java文gQ已l改完)?BR> 2、我把包含SQLPool 的java文g改了一遍,?7个java文gQ已l改完)?BR> 3、我把不用的jsp文g整理了一下,大概?7 个目录的jsp文g不用或者没有上Uѝ(整理完毕Q?BR>问题11Q提交页面,每次都提交两ơ?BR>原因Q?BR> 1?BR><input type="submit" name="sendit" value="发? class=button onclick="javascript:if(chkit())form_submit('broadcast_operation.jsp?s_coming=1&s_num=<%=str_num%>')"> q里如果type=”sbumit?面׃提交两次。(p了一天的旉才找到原因)?BR>在onclick事g里面会提交一ơ,而submit 按钮本n也会提交一ơ?BR> 解决ҎQ?BR> 如果在onclick 事g里面提交面Q按钮的cdtype 一定不可以是”submit?nbsp; 按钮?BR>可以是”button? 全文搜烦共有33个类似的文g?BR>java.net.SocketException: ReadFile failed: 指定的网l名不再可用?BR>主要是由于这个引L?BR>问题12Q定时刷新页面,600U(不是必要的,不要q样做) 原因Q?BR> <meta http-equiv="refresh" content="600"> 解决ҎQ?BR> Lq样的语句?BR> 全文搜烦共有12个类似的文g?BR> 问题13Q在跌{到别的页面的时候,要加return?BR>否则可能会引起错误。蟩转不q去?BR>If{ request.getRequestDispatcher("/zjdx/jsp/common/ErrorPage.jsp?s_mark=error:record have existed").forward(request,response); return; } else { response.sendRedirect(); //用上面的Ҏ return; } |