JavaServlet:如何加快速度?
我有下面的函数,它是为生成的每个行项目调用的。有人知道如何加快速度吗JavaServlet:如何加快速度?,java,performance,optimization,servlets,Java,Performance,Optimization,Servlets,我有下面的函数,它是为生成的每个行项目调用的。有人知道如何加快速度吗 private String getDetails(String doc){ String table=""; java.sql.ResultSet rs = qw.DBquery("select " + "id,LineType, QtyTotal, ManufacturerPartNumber, Description, UnitCost,UnitPrice " + "Fro
private String getDetails(String doc){
String table="";
java.sql.ResultSet rs = qw.DBquery("select " +
"id,LineType, QtyTotal, ManufacturerPartNumber, Description, UnitCost,UnitPrice " +
"From DocumentItems " +
"where DocID="+doc+" order by linenumber " +
"");
table+= "<table class=inner><thead><colgroup><col id='col1'><col id='col2'><col id='col3'><col id='col4'><col id='col5'></colgroup>" +
"<tr class='enetBlue'><th>Qty</th><th>Part Num</th><th>Description</th><th>Unit Cost</th><th>Unit Price</th></tr></thead>" +
"<tbody>";
try{
int odd = 0;
while(rs.next()){
int lineType = rs.getInt("LineType");
int qty = rs.getInt("QtyTotal");
String part = rs.getString("ManufacturerPartNumber");
String desc = rs.getString("Description");
float cost = rs.getFloat("UnitCost");
float price = rs.getFloat("UnitPrice");
String id = rs.getString("id");
String clas="";
if (odd==0) odd=1; else odd=0;
clas="red";
if (lineType==2) clas="yellow";
if (lineType==3) clas="yellow";
if (lineType==4) clas="yellow";
if (qty==0) clas="yellow";
java.sql.ResultSet rs2 = mas.DBquery("select itemkey from timitem where itemid = '"+part+"'");
while (rs2.next())
{
if (odd==1) clas="odd";
if (odd==0) clas="even";
}
table+="<tr class='"+clas+"'><td>"+qty+"</td>\n"+
"<td>"+part+"</td>\n"+
"<td>"+desc+"</td>\n"+
"<td>"+cost+"</td>\n"+
"<td>"+price+"</td></tr>\n";
//if clas=red | means item is not found in MAS, gear for insert.
if (clas=="red") {
table+="<tr ><td colspan=5><table border=1><tr><td colspan=2>\n";
//get unit measure key
try {
table+="<form name=masinsert"+id+" method=get action=MASInsert>\n";
table+="<input type=hidden name=\"partnumber"+id+"\" value=\""+part+"\">\n";
table+="<input type=hidden name=\"itemcost"+id+"\" value=\""+cost+"\">\n";
table+="<input type=hidden name=\"itemlistprice"+id+"\" value=\""+price+"\">\n";
table+="<input type=hidden name=\"itemdescription"+id+"\" value=\""+desc+"\">\n";
table+="</td><tr>\n";
java.sql.ResultSet rsUM = mas.DBquery("select * from tciUnitMeasure where companyid like 'ENS' ");
table+="<tr bgcolor=#990033><td align=left valign=top>Unit Measure</td><td align=left valign=top><select name=\"UnitMeasKey\">";
while(rsUM.next())
{
table+="<option value=\"" + rsUM.getString("UnitMeasKey") + "\">" + rsUM.getString("UnitMeasID") + "</option>\n";
}//end while rs1
table+="</select></td></tr>\n";
//build ItemClass options from mas: Puchase ProductLine
java.sql.ResultSet rsPP = mas.DBquery("select * from timPurchProdLine where companyID = 'ENS'");
int k = 0;
table+= "<tr bgcolor=#990033><td align=left valign=top>Purchase Product Line</td><td align=left valign=top><select name=\"PurchProdLine\">\n";
while(rsPP.next())
{
table+="<option value=\"" + rsPP.getString("PurchProdLineKey") + "\">" + rsPP.getString("Description") + "</option>\n";
}//end while rsPP
table+="</select></td></tr>\n";
//build item classkey options
java.sql.ResultSet rsIC = mas.DBquery("select * from timItemClass where companyID = 'ENS' order by itemclassname desc");
table+= "<tr bgcolor=#990033><td align=left valign=top>Item Class :</td><td align=left valign=top><select name=\"itemclasskey\">\n";
while(rsIC.next())
{
table+="<option value=\"" + rsIC.getString("itemclasskey") + "\">" + rsIC.getString("ItemClassName") + "</option>\n";
}//end while rs1
table+="</select></td></tr>";
table+="<tr><td colspan=2><input id='m"+id+"' type=\"button\" onclick=\"masinsert('"+ id +"')\" value=\"Add to MAS\"></td></tr>";
table+="</table>\n";
}catch(Exception e){} //end try
table+="</form>\n";
table+="</td></tr>";
}//end if clas=red
}//end while
}catch(java.sql.SQLException e){
e.printStackTrace();}
table+="</tbody></table>";
return table;
}
私有字符串获取详细信息(字符串文档){
字符串表=”;
java.sql.ResultSet rs=qw.DBquery(“选择”+
id、线型、QTY总计、制造商零件号、说明、单位成本、单价+
“来自文档项”+
“其中DocID=“+doc+”按行号排序”+
"");
表+=“”+
“QtyPart NUM说明单位成本单价”+
"";
试试{
int奇数=0;
while(rs.next()){
int线型=rs.getInt(“线型”);
整数数量=rs.getInt(“QtyTotal”);
字符串部分=rs.getString(“制造商零件号”);
String desc=rs.getString(“说明”);
浮动成本=rs.getFloat(“单位成本”);
浮动价格=rs.getFloat(“单价”);
字符串id=rs.getString(“id”);
字符串clas=“”;
如果(奇数=0)奇数=1;否则奇数=0;
clas=“红色”;
如果(线型==2)clas=“黄色”;
如果(线型==3)clas=“黄色”;
如果(线型==4)clas=“黄色”;
如果(数量==0)clas=“黄色”;
java.sql.ResultSet rs2=mas.DBquery(“从timitem中选择itemkey,其中itemid='“+part+'”);
while(rs2.next())
{
如果(奇数==1)clas=“奇数”;
如果(奇数==0)clas=“偶数”;
}
表+=“”+数量+“\n”+
“+部分+”\n”+
“+desc+”\n”+
“+成本+”\n”+
“+price+”\n”;
//如果clas=红色|表示在MAS中未找到项目,则插入齿轮。
如果(clas==“红色”){
表+=“\n”;
//获取单位度量键
试一试{
表+=“\n”;
表+=“\n”;
表+=“\n”;
表+=“\n”;
表+=“\n”;
表+=“\n”;
java.sql.ResultSet rsUM=mas.DBquery(“从tciUnitMeasure中选择*,其中公司喜欢“ENS”);
表+=“单位度量”;
while(rsUM.next())
{
表+=“”+rsUM.getString(“UnitMeasID”)+“\n”;
}//在rs1时结束
表+=“\n”;
//从mas:Puchase产品线生成ItemClass选项
java.sql.ResultSet rsPP=mas.DBquery(“从timPurchProdLine中选择*,其中companyID='ENS'”);
int k=0;
表+=“采购产品线\n”;
while(rsPP.next())
{
表+=“”+rsPP.getString(“说明”)+“\n”;
}//在rsPP时结束
表+=“\n”;
//生成项类键选项
java.sql.ResultSet rsIC=mas.DBquery(“从timItemClass中选择*,其中companyID='ENS'按itemclassname desc排序”);
表+=“项目类别:\n”;
while(rsIC.next())
{
表+=“”+rsIC.getString(“ItemClassName”)+“\n”;
}//在rs1时结束
表+=”;
表+=”;
表+=“\n”;
}catch(异常e){}//end try
表+=“\n”;
表+=”;
}//如果clas=红色,则结束
}//结束时
}catch(java.sql.sqle){
e、 printStackTrace();}
表+=”;
返回表;
}
提前感谢使用“+”运算符追加字符串速度非常慢,因为由于字符串的不变性,JVM需要为每次追加迭代字符串中的每个字符 调查 您还可以使用SQL s,而不必迭代每个记录并制定新的查询。实际上,您只需要访问数据库一次 循环中还有一个查询,它始终返回相同的数据:
java.sql.ResultSet rsUM = mas.DBquery("select * from tciUnitMeasure where companyid like 'ENS' ");
这应该被移到循环之外,尽管我怀疑您可能能够使用联接消除这一查询和其他嵌套查询。我将缓存键入doc参数的函数的输出。根据应用程序的使用模式,它可以极大地提高应用程序的速度 学习如何编写JSP并停止在servlet中嵌入HTML和CSS。这在1998年是个坏主意,当时很普遍;从那以后,我们已经取得了长足的进步 当您在一个ResultSet上循环并在循环内执行查询时,这意味着您在第一次查询中返回的每一行都有一个网络往返。这肯定是你问题的最大瓶颈。首先要消除这一点 我建议将数据库代码移出servlet,放入一个持久性对象中,您无需启动servlet引擎即可进行测试
这种方法根本没有面向对象的功能。看起来像发票或物料清单,但我看不到任何对象。使用预编译的参数化PreparedStation,而不是每次使用字符串连接来构建它。这还将修复当前代码(如果doc是用户输入的变量)易受SQL注入攻击的事实 您有一个
select*from timPurchProdLine,其中companyID='ENS'
行,您在每次迭代中运行该行。该表的内容会随着每次迭代而改变吗?因为如果它们是静态的,如果你只阅读ta的内容,你会节省很多时间
java.sql.ResultSet rs2 = mas.DBquery(...);
while (rs2.next())
{
if (odd==1) clas="odd";
if (odd==0) clas="even";
}
boolean odd = false;
...
odd = !odd; // instead of your if statement
...
clas = odd ? "odd" : "even"; // inside the while loop.
String clas = "";
...
clas = "red";
// String clas = ""; remove this line
...
String clas = "red";
if (clas == "red") {
if ("red".equals(clas))
java.sql.ResultSet rsPP = mas.DBquery("select * from timPurchProdLine where companyID = 'ENS'");
private String timItemClassTable() throws SQLException {
StringBuffer sb = new StringBuffer();
ResultSet rs = mas.DBquery("select * from timItemClass where companyID = 'ENS' order by itemclassname desc");
sb.append("<tr bgcolor=#990033><td align=left valign=top>Item Class :</td><td align=left valign=top><select name=\"itemclasskey\">\n");
while (rs.next())
sb.append(String.format("<option value=\"%s\">%s</option>\n", rs.getString("itemclasskey"), rs.getString("ItemClassName")));
sb.append("</select></td></tr>");
return sb.toString();
}
import java.sql.ResultSet;
import java.util.List;
import java.util.ArrayList;
// etc etc. etc
public class SomeServlet extends HttpServlet {
// ALL THE FOLLOWING ARE CONSTANTA IN THE SERVLET.
// THEIR VALUE DOES'T CHANGE DURING EXECUTION
private static final String SELECT_DOCUMENT_QUERY =
"SELECT \n" +
" id,LineType, QtyTotal, ManufacturerPartNumber, Description, UnitCost,UnitPrice \n" +
" FROM DocumentItems \n" +
" WHERE DocID=%s order by linenumber ";
private static final String HTML_HEADER_TABLE =
"<table class=inner><thead><colgroup><col id='col1'>"+
"<col id='col2'><col id='col3'><col id='col4'><col id='col5'></colgroup>" +
"<tr class='enetBlue'><th>Qty</th><th>Part Num</th><th>Description</th>"+
"<th>Unit Cost</th><th>Unit Price</th></tr></thead><tbody>";
// These constants are the HTML Commbo for the given queries.
// If they are initialized once at the beginning will increase
// the servlets performace considerabily.
private static final String UNIT_MEASURES_COMBO =
getCombo( "Unit Measure", "UnitMeasKey",
getListFrom( "select * from tciUnitMeasure where companyid like 'ENS' ") );
private static final String ITEM_CLASS_COMBO =
getCombo( "Purchase Product Line", "PurchProdLine",
getListFrom( "select * from timPurchProdLine where companyID = 'ENS' ") );
private static final String CLASS_KEY_COMBO =
getCombo( "Item Class :", "itemclasskey",
getListFrom( "select * from timItemClass where companyID = 'ENS' order by itemclassname desc") );
// Use a class to separete domain objects from presentation
// This class becomes handy do pass data through methods.
class Document {
int lineType;
int qty;
String part;
String desc;
float cost;
float price;
String id;
}
// simple clas that holds a key/value pair
class ComboPair {
String key;
String value;
public ComboPair( String key, String value ) {
this.key = key;
this.value = value;
}
}
/*
* Finally the fixed code.
*
* Basically a method should do only one thig. If the method is doing a lot of things
* several functionality at the same time, it should delegate the details of the subfunctionality
* to another function. This way each function or method is easier to read/maintain/understand.
* This method should read like this:
*
* For a given docId,
* - query the database and display details of the document
* - if the document is not present in mas?
* - create a form to inser it
*
* differntiate each record with different style.
*/
private String getDetails(String doc){
// Close each result set before openning a new one.
ResultSet rs = qw.DBquery( String.format( SELECT_DOCUMENT_QUERY, doc ));
List<Document> documents = new ArrayList<Document>();
while(rs.next()){
documents.add( createDocumentFrom( rs ));
}
// Iterate through
StringBuilder resultingTable = new StringBuilder( HTML_HEADER_TABLE );
boolean isEven = false;// starts as odd
for( Document doc : documents ) {
String clazz = getClassFor( doc , isEven );
isEven = !isEven;
resultingTable.append("<tr class='"+clazz+"'>"+
"<td>"+doc.qty+"</td>\n"+
"<td>"+doc.part+"</td>\n"+
"<td>"+doc.desc+"</td>\n"+
"<td>"+doc.cost+"</td>\n"+
"<td>"+doc.price+"</td></tr>\n");
if( needsInsertForm( clazz ) ) {
resultingTable.append( getInsertForm( document ) );
}
resultingTable.append("</tbody></table>");
}
return table;
}
/**
* This methods craates an instance of "Document".
* Instead of mixing the fetch code with the render code
* this method allows to separete the data from its presentation
*/
private Document createDocumentFrom( ResultSet rs ) {
Document document = new Document();
document.lineType = rs.getInt("LineType");
document.qty = rs.getInt("QtyTotal");
document.part = rs.getString("ManufacturerPartNumber");
document.desc = rs.getString("Description");
document.cost = rs.getFloat("UnitCost");
document.price = rs.getFloat("UnitPrice");
document.id = rs.getString("id");
return document;
}
// Computes the correct css class for the given document.
private static String getClassFor( Document document, boolean isEven ) {
String clazz = "red";
switch( document.lineType ) {
case 2:
case 3:
case 4: clazz ="yellow";
}
if( document.qty == 0 ) {
clazz = "yellow";
}
ResultSet rs = mas.DBquery( String.format("select itemkey from timitem where itemid = '%s'", document.part);
while (rs.next()) {
clazz = isEven? "even" : "odd";
}
rs.close();
return clazz;
}
// Creates the inser form for the given document
private static String getInsertForm( Document document ) {
StringBuilder form = new StringBuilder();
form.append("<tr ><td colspan=5><table border=1><tr><td colspan=2>\n");
form.append("<form name=masinsert"+document.id+" method=get action=MASInsert>\n");
form.append("<input type=hidden name=\"partnumber"+document.id+"\" value=\""+document.part+"\">\n");
form.append("<input type=hidden name=\"itemdescription"+document.id+"\" value=\""+document.desc+"\">\n");
form.append("<input type=hidden name=\"itemcost"+document.id+"\" value=\""+document.cost+"\">\n");
form.append("<input type=hidden name=\"itemlistprice"+document.id+"\" value=\""+document.price+"\">\n");
form.append("</td><tr>\n");
//----------------------------------------------------------------------------------------------------------------------------
//get unit measure key
form.append(UNIT_MEASURES_COMBO);
//build ItemClass options from mas: Puchase ProductLine
form.append(ITEM_CLASS_COMBO);
//build item classkey options
form.append( CLASS_KEY_COMBO);
//----------------------------------------------------------------------------------------------------------------------------
form.append("<tr><td colspan=2><input id='m"+document.id+"' type=\"button\" onclick=\"masinsert('"+ document.id +"')\" value=\"Add to MAS\"></td></tr>");
form.append("</table>\n";
form.append("</form>\n";
form.append("</td></tr>");
return form.toString();
}
// This is an utility method that reads bettern when used in the
// main method.
// if( needsInsertForm( clazzz ) ) {
// is much clearer
private static boolean needsInsertForm( String clazz ) {
return "red".equals(clazz);
}