简体   繁体   English

JSP临时存储重复数据库结果

[英]JSP Temporary storing Repetitive Database Results

I have a following code in JSP which runs repetitively each time user visits the page. 我在JSP中有以下代码,每次用户访问该页面时,该代码都会重复运行。 The values of database result are same for all the visitors. 所有访客的数据库结果值均相同。 This page takes parameter "service" and SQL query is performed based on it. 该页面接受参数“ service”,并基于该参数执行SQL查询。 The second SQL query is performed based on "id" generated by first query. 基于第一个查询生成的“ id”执行第二个SQL查询。 If there are 20 different Services it runs the following queries 20 times and then only shows the page. 如果有20种不同的服务,它将运行以下查询20次,然后仅显示该页面。 So, is there any way how I can store these result temporarily (using cache or something) such that these queries are run only once/first visit and then for other request Database requests are not made?? 因此,有什么方法可以临时存储这些结果(使用缓存或其他方法),使得这些查询仅运行一次/第一次访问,然后针对其他请求不进行数据库请求? such that the page loads very fast and it doesn't consume any cpu/memory.. I can only do this in JSP, and have apache tomcat 6. 这样页面加载速度非常快,并且不占用任何CPU /内存。.我只能在JSP中执行此操作,并且要使用apache tomcat 6。

 ================= EDITED PART================

I found first solution by implementing application.getAttribute()/setAttribute() saying.. 我通过实现application.getAttribute()/ setAttribute()的说法找到了第一个解决方案。

 if(application.getAttribute(service)==null
 {
    //do first query
    application.setAttribute(service,name);
 } 
else name=application.getAttribute(service);

Now how to use id parameter in second query??? 现在如何在第二个查询中使用id参数? Please advise.. 请指教..

=============================================

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

Thanks in advance! 提前致谢!

First of all, don't use string concatenation to build your SQL queries. 首先,不要使用字符串连接来构建您的SQL查询。 Use prepared statements. 使用准备好的语句。 This is a security hole and there is no excuse to miss that point. 这是一个安全漏洞,没有任何理由错过这一点。

Then be warned that it is considered bad style to use Java code inside JSP pages. 然后警告,在JSP页面内使用Java代码被认为是不好的风格。 This may lead to unmaintainable code. 这可能会导致代码无法维护。 In the majority of cases it is best to stick by that rule. 在大多数情况下,最好遵守该规则。 But to be realistic, sometimes under some circumstances it is best to break that rule. 但是要现实一些,有时在某些情况下最好打破该规则。 The responsible developer should decide after balance pros and cons. 负责任的开发人员应权衡利弊后再决定。

If you decide to write Java into your JSP then do it right. 如果您决定将Java写入您的JSP,请正确执行。 Be secure, use prepared statements, validate your input parameters (is a 1000 char or null id a valid id?) and synchronize concurrent access. 为安全起见,请使用准备好的语句,验证您的输入参数(1000个字符或空ID是否为有效ID?)并同步并发访问。

As a poor man's cache you can use simple Map instances (maybe one for each SQL query) and store the maps into application scope. 作为穷人的缓存,您可以使用简单的Map实例(每个SQL查询可能一个),并将地图存储到应用程序范围内。 Use synchronization to access and change these maps. 使用同步来访问和更改这些地图。

For each map create a parameter class and a result class. 为每个映射创建一个参数类和一个结果类。

For example (with Apache Commons Lang EqualsBuilder and HashCodeBuilder ): 例如(使用Apache Commons Lang EqualsBuilderHashCodeBuilder ):

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 ...
}

Then your first map could be of type Map<TextsParam, TextsResult> . 然后,您的第一个地图可能是Map<TextsParam, TextsResult>

In your code, after you checked that parameters service and webdomain are not null and valid, you create a TextsParam instance with these parameters and check if your map already contains that key. 在代码中,检查参数servicewebdomain不为null和有效后,您将使用这些参数创建TextsParam实例,并检查地图是否已包含该键。 If yes, use the corresponding TextsResult value. 如果是,请使用相应的TextsResult值。 Otherwise execute the database query and store the result in to your map for later use. 否则,请执行数据库查询并将结果存储到您的地图中以备后用。 Don't forget to put that code into a synchronized block (or better a synchronized method). 不要忘记将代码放入synchronized块(或更好的同步方法)中。

Be aware that an entry added to your map will never be deleted. 请注意,添加到地图的条目将永远不会被删除。 So this will work only for a manageable size of cachable values. 因此,这仅适用于可管理值的可管理大小。 The next step would be to use a Map implementation which automatically removes old values like a LRU cache . 下一步将是使用Map实现,该实现将自动删除旧值,例如LRU缓存

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM