使用 Ajax 的 Java Servlet DB 查询 - 查询时间慢且查询字符串并不总是完全传递给 servlet
我正在尝试使用 Java EE 和 Servlet 创建基于 AJAX 的 SQL 查询。我在客户端使用 Glassfish 3.01 和 MS SQL 服务器以及 Jquery。 我将所有内容放在一起,并将我的 ajax 函数绑定到文本字段的 onkeyup 事件。但有时当我将“teststring”放入文本框中时,只有“teststrin”传递给Servlet。所以基本上最后一个字符消失了,因此查询结果不正确。 更不用说当结果集包含大量数据时,查询速度相当慢。您能检查一下我在服务器端和客户端是否做错了什么吗?
在客户端我有这个 JQuery 函数:
function ajaxSearch(sstring) {if (字符串长度 < 3) { $("#external").html("
请至少 3 个字符......
") } else { $('#loading').ajaxStart(function() { $(this).show() $("#external").hide() });$('#loading').ajaxComplete(function() { $(this).hide() $("#external").show() }); $.ajax({ type:"GET", url: "/myApp/getStd", dataType: "application/x-www-form-urlencoded", data: "sstring="+escape(sstring), async: true, success: function(data){ $("#external").html(data); } })
} 提前
在服务器端我有这个:
@WebServlet(name="getStd", urlPatterns={"/getStd"}) public class getStd extends HttpServlet { @Override public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection conn = null; Statement stmt = null; ResultSet rs = null; ArrayList rows = new ArrayList(); res.setCharacterEncoding("UTF-8"); res.setContentType("text/html"); PrintWriter out = res.getWriter(); String sql=null; String test= req.getParameter("sstring"); try{ InitialContext cxt = new InitialContext(); if (cxt == null) { throw new Exception("Uh oh -- no context!");} DataSource ds = (DataSource) cxt.lookup( "jdbc/Sample" ); conn = ds.getConnection(); stmt = conn.createStatement(); sql="Select * from MYDB.dbo.testdb where myField like '%"+req.getParameter("sstring")+"%';"; rs = stmt.executeQuery(sql); while(rs.next()){ stdRecord cols = new stdRecord(); cols.setTeljel(rs.getString("Field1")); cols.setTitle(rs.getString("Field2")); cols.setICS(rs.getString("Field3")); cols.setREF(rs.getString("Field4")); rows.add(cols); } req.setAttribute("std", rows); req.setAttribute("query",test ); req.getRequestDispatcher("/showRes.jsp").forward(req, res); // close everything to free up resources rs.close(); rs = null; stmt.close(); stmt = null; conn.close(); / conn = null; rows=null; } catch (SQLException e) { e.printStackTrace(out); } catch (Exception e) { e.printStackTrace(out); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { ; } rs = null; } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { ; } stmt = null; } if (conn != null) { try { conn.close(); } catch (SQLException e) { ; } conn = null; } } } }
致谢。
I'm trying to create a AJAX based SQL query with Java EE and Servlets. I'm using Glassfish 3.01 and MS SQL server with Jquery on the client side.
I put everything together, and bind my ajax function to the textfield's onkeyup event. But sometimes When I put 'teststring' into the textbox only "teststrin" passed to the Servlet. So basically the last char disappears and therefore the query result is not correct.
Not to mention when the resultset contains large amount of data the query is pretty slow. Could you please check if I'm doing something wrong on the server and client side?
On the client side I have this JQuery function:
function ajaxSearch(sstring) {if (sstring.length < 3) { $("#external").html("
at least 3 chars please....
") } else { $('#loading').ajaxStart(function() { $(this).show() $("#external").hide() });$('#loading').ajaxComplete(function() { $(this).hide() $("#external").show() }); $.ajax({ type:"GET", url: "/myApp/getStd", dataType: "application/x-www-form-urlencoded", data: "sstring="+escape(sstring), async: true, success: function(data){ $("#external").html(data); } })
}
}On the server side I have this:
@WebServlet(name="getStd", urlPatterns={"/getStd"})
public class getStd extends HttpServlet {
@Override
public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
ArrayList rows = new ArrayList();
res.setCharacterEncoding("UTF-8");
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String sql=null;
String test= req.getParameter("sstring");
try{
InitialContext cxt = new InitialContext();
if (cxt == null) {
throw new Exception("Uh oh -- no context!");}
DataSource ds = (DataSource) cxt.lookup( "jdbc/Sample" );
conn = ds.getConnection();
stmt = conn.createStatement();
sql="Select * from MYDB.dbo.testdb where myField like '%"+req.getParameter("sstring")+"%';";
rs = stmt.executeQuery(sql);while(rs.next()){
stdRecord cols = new stdRecord();
cols.setTeljel(rs.getString("Field1"));
cols.setTitle(rs.getString("Field2"));
cols.setICS(rs.getString("Field3"));
cols.setREF(rs.getString("Field4"));
rows.add(cols);
}req.setAttribute("std", rows);
req.setAttribute("query",test );
req.getRequestDispatcher("/showRes.jsp").forward(req, res);
// close everything to free up resources
rs.close();
rs = null;
stmt.close();
stmt = null;
conn.close(); /
conn = null;
rows=null;
} catch (SQLException e) {
e.printStackTrace(out);
} catch (Exception e) {
e.printStackTrace(out);
} finally {
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
rs = null;
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
stmt = null;
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
conn = null;
}}
}
}Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
至于keyup的延迟,我认为这与性能问题有关,所以我们先解决这个问题,然后再回顾。
至于性能,您提供的有关设置的信息非常少,但是初学者经常忽略的两个常见解决方案如下:
使用连接池
DataSource
而不是驱动管理器。这节省了每次查询时连接数据库的成本(这可能需要超过 200 毫秒,而池连接会立即返回)。有关详细信息,请参阅相关应用程序服务器的 JNDI 资源配置文档(提示:管理控制台 )。
在 SQL 端而不是 Java 端限制结果集大小。这节省了通过网络传输不相关数据的成本。只需返回前 10 个结果或其他内容,而不是整个表。有关详细信息,请参阅相关数据库的 SQL 手册(提示:
SET ROWCOUNT
)。As to the lag in keyup, I think this is related to the performance issue, so let's fix that first and then review afterwards.
As to the performance, you've given very little information about your setup, but two common solutions which are often overlooked by starters are the following:
Use a connection pooled
DataSource
instead ofDriverManager
. This saves the cost of connecting the DB on every query (which can take over 200ms while a pooled connection is returned in no-time). Consult the JNDI resource config documentation of the application server in question for details (hint: admin console).Limit the resultset size in SQL side instead of in Java side. This saves the cost of transferring irrelevant data over network. Just return the top 10 results or something instead of the entire table. Consult the SQL manual of the database in question for details (hint:
SET ROWCOUNT
).