[英]JSP Temporary storing Repetitive Database Results
我在JSP中有以下代码,每次用户访问该页面时,该代码都会重复运行。 所有访客的数据库结果值均相同。 该页面接受参数“ service”,并基于该参数执行SQL查询。 基于第一个查询生成的“ id”执行第二个SQL查询。 如果有20种不同的服务,它将运行以下查询20次,然后仅显示该页面。 因此,有什么方法可以临时存储这些结果(使用缓存或其他方法),使得这些查询仅运行一次/第一次访问,然后针对其他请求不进行数据库请求? 这样页面加载速度非常快,并且不占用任何CPU /内存。.我只能在JSP中执行此操作,并且要使用apache tomcat 6。
================= EDITED PART================
我通过实现application.getAttribute()/ setAttribute()的说法找到了第一个解决方案。
if(application.getAttribute(service)==null
{
//do first query
application.setAttribute(service,name);
}
else name=application.getAttribute(service);
现在如何在第二个查询中使用id参数? 请指教..
=============================================
String service=request.getParameter("service");
sqlstr = "SELECT uniqueid,name,body FROM tbl_texts WHERE
serviceunique='"+service+"' AND webdomain='" + webdomain + "'";
rs = DbUtils.getRs(con,sqlstr);
if (rs.next()) {
id = rs.getString("uniqueid");
name = rs.getString("name");
body=rs.getString("body");
}
rs.close();
sqlstr = "SELECT animage,awidth,aheight FROM tbl_Images WHERE
uniqueid='" + id + " AND profile='" + imageprofile + "'";
rs = DbUtils.getRs(con,sqlstr);
if (rs.next()) {
images = rs.getString("animage");
size= (int) (rs.getDouble(awidth) * rs.getDouble(rs.getDouble(aheight) )
rs.close();
提前致谢!
首先,不要使用字符串连接来构建您的SQL查询。 使用准备好的语句。 这是一个安全漏洞,没有任何理由错过这一点。
然后警告,在JSP页面内使用Java代码被认为是不好的风格。 这可能会导致代码无法维护。 在大多数情况下,最好遵守该规则。 但是要现实一些,有时在某些情况下最好打破该规则。 负责任的开发人员应权衡利弊后再决定。
如果您决定将Java写入您的JSP,请正确执行。 为安全起见,请使用准备好的语句,验证您的输入参数(1000个字符或空ID是否为有效ID?)并同步并发访问。
作为穷人的缓存,您可以使用简单的Map
实例(每个SQL查询可能一个),并将地图存储到应用程序范围内。 使用同步来访问和更改这些地图。
为每个映射创建一个参数类和一个结果类。
例如(使用Apache Commons Lang EqualsBuilder和HashCodeBuilder ):
class TextsParam {
private String service;
private String webdomain;
// Getters and setters ...
@Override
public boolean equals(Object obj) {
if(obj == null) { return false; }
if(obj == this) { return true; }
if(obj.getClass() != getClass()) {
return false;
}
TextsParam other = (TextsParam) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(service, other.service)
.append(webdomain, other.webdomain)
.isEquals();
}
@Override
public int hashCode() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(17, 37)
.append(service)
.append(webdomain).
.toHashCode();
}
}
class TextsResult {
private String id;
private String name;
private String body;
// Getters and setters ...
}
然后,您的第一个地图可能是Map<TextsParam, TextsResult>
。
在代码中,检查参数service
和webdomain
不为null和有效后,您将使用这些参数创建TextsParam
实例,并检查地图是否已包含该键。 如果是,请使用相应的TextsResult
值。 否则,请执行数据库查询并将结果存储到您的地图中以备后用。 不要忘记将代码放入synchronized
块(或更好的同步方法)中。
请注意,添加到地图的条目将永远不会被删除。 因此,这仅适用于可管理值的可管理大小。 下一步将是使用Map
实现,该实现将自动删除旧值,例如LRU缓存 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.