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);
    }