关于ResultSet设置到request属性的问题(非常神奇)

算法导论 2011-08-28 01:33:06
若有哪个高手给出解释,高分奉送。再加一个深深的鞠躬!

背景:当我学了点Java Web之后,也具备了数据库知识之后,就开始自作聪明了,我没有去了解那些主流框架是把获得数据库连接的代码写在哪里,而我心想,数据库操作的步骤无非就是获得Connection,再通过它创建Statement对象,然后再通过Statement对象进行execute、executeQuery等方法执行sql语句。所以我就把stmt对象设到ServletContext对象的属性中去,这样整个应用里的servlet们可以共用到Statement对象,只要从ServletContext里拿stmt属性就可以操作数据库了,不是很方便吗?那什么时候把Statement对象设到ServletContext里呢,在ServletContextListenner里,也就是说启动Tomcat后,创建ServletContext对象的时候就把Statement对象设置到它的属性里去了


问题(关键):我在servlet里把结果集rs(ResultSet对象)设到request对象里,再将它转发给一个jsp,jsp里从request里getAttribue结果集,结果不能显示。原因竟然是这样,我在jsp里获得statement的对象是用如下语句:
Statement stmt = (Statement)application.getAttribute("stmt");//从ServletContext对象获得stmt

而如果将其改成从头到尾重新获得conn、再创建stmt就可以用,如下代码:
Class.forName("org.postgresql.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/。。。","。。。。","。。。。");
Statement stmt = conn.createStatement();

竟然就可以了。问题是我要显示的内容是从request属性里取得rs结果集的,和stmt对象不搞

就是这个页面http://stdlib.gicp.net/mobile/就是点分页的时候交给一个servlet处理再将结果集转发回来,如果Statement对象从Context里取,主页内容显示没问题(它的显示是用stmt对象执行sql语句获得的),如果点分页就什么都不显示。
换成第二种写法就正常显示分页。
非常奇特!!
...全文
337 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
算法导论 2011-08-31
  • 打赏
  • 举报
回复
这个问题我得重新问过,写得太长。没人愿意看完
算法导论 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jike316 的回复:]
引用 11 楼 jike316 的回复:

首先楼主直接把statement放在request中这种做法是很少的机会没人这么干,这样很不安全。照你说的,肯定是你其他什么地方写错了。自己多看看,多debug下

也很影响性能的
[/Quote]
我哪里把Statement放到request里了,我是放在ServletContext里,全局的,所有servlet都能访问到
codeallen 2011-08-29
  • 打赏
  • 举报
回复
看了下楼主的代码和描述。

首先不说楼主代码的bug

我们写代码的时候要尽量降低代码的耦合度,应该个dao-->service-->action-->page层层可以独立的。

jdbc最好是一个Connection生产出一个statement对象,因为你的项目有可能是双数据库,这样写的代码也易于维护,可以很快的适应新的需求。

建议楼主先看看三层是如何划分的在来写jdbc+servlet也不急,等摸透了前辈的三层思想在加以创新也不急。

希望可以帮助到你
小绵羊 2011-08-29
  • 打赏
  • 举报
回复
用离线数据集吧
http://topic.csdn.net/u/20110829/08/e5e13d40-78d4-4462-a3c9-c9ffeac70eb3.html?81030
拿去改改就能用,能满足基本的需求
liyang1271989 2011-08-29
  • 打赏
  • 举报
回复
今天刚看了一个帖子, lz是不是想实现离线数据集?
2399 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jike316 的回复:]

首先楼主直接把statement放在request中这种做法是很少的机会没人这么干,这样很不安全。照你说的,肯定是你其他什么地方写错了。自己多看看,多debug下
[/Quote]
也很影响性能的
2399 2011-08-28
  • 打赏
  • 举报
回复
首先楼主直接把statement放在request中这种做法是很少的机会没人这么干,这样很不安全。照你说的,肯定是你其他什么地方写错了。自己多看看,多debug下
zwswin 2011-08-28
  • 打赏
  • 举报
回复
观摩一下
算法导论 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 chuaizicai 的回复:]
额。。。求所有代码,说了这么多,没有把代码全贴出来给力
[/Quote]
我担心代码太多会引起反感,好吧我贴出来,很乱。
JSP代码:
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page language="java" import="java.sql.*" %>



<html>
<head><title>杨笑天官网</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><style type="text/css">

<!--
.textarea{font-size:12px; height:20px;}
.STYLE1 {font-size: 12px}
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: none;
}
a:active {
text-decoration: none;
}
-->
</style>
<script language="javascript">
function checkForm()
{
if(words.words.value=="")
{
alert("留言内容不能为空");
words.words.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<p><img src="images/top.gif" > </p>
<%

try{
Class.forName("org.postgresql.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/filedun","此处保密","此处保密");
Statement stmt = conn.createStatement();
//Statement stmt = (Statement)application.getAttribute("stmt");
String name = (String)session.getAttribute("name");

ResultSet rs1 = (ResultSet) stmt.executeQuery("SELECT count(*) totalCount FROM wordsdetails");
rs1.next();
int count=rs1.getInt("totalCount");
int i,pages=0,n=1;
if(count>10 && count%10==0) pages=count/10; //如果是10的倍数
else if(count>10) pages=count/10+1;


String strPage = request.getParameter("page");
if(strPage!=null) n = Integer.parseInt(strPage);

if(name!=null){%>
<p class="STYLE1">你好,<%=name%></p>

<form name="words" method="post" action="insert.do" onSubmit="return checkForm();">
<label>
<input name="words" type="text" size="8" maxlength="200">
</label>
<label>
<input type="submit" name="Submit" value="留言">
</label>
</form>
<%}else{%>
<p class="STYLE1"><a href="register.jsp">注册</a>|<a href="login.jsp">登录</a> →<a href="http://stdlib.gicp.net">PC版</a></p>

<%}%>
<p class="STYLE1">
<%
if(n>1) {%>
<a href="./showPage.do?page=<%=n-1%> ">上页</a>

<%
}
for(i=1;i<=pages;i++)
{
if(n==i) {
%>

<%=i%>
<%
}else {
%>
<a href="./showPage.do?page=<%=i%> "><%=i%></a>




<%
}}
if(n<pages){%>
<a href="./showPage.do?page=<%=n+1%> ">下页</a>
<%}%>
</p>
<%

String query= "select * from wordsdetails order by speakdate DESC limit 10";

ResultSet rs=null;
rs = (ResultSet)request.getAttribute("rs");
if(rs==null)
rs = (ResultSet)stmt.executeQuery(query);


%>

<%while(rs.next()){
%>

<div style= "width:200px "><p class="STYLE1"><%=rs.getString("speakdate")%>【<%=rs.getString("name")%>】说:<%=rs.getString("words")%><%if(name!=null&&name.equals("管理员")){%><form action="deleteWords.do" method="post"><input type="hidden" name="ID" value=<%=rs.getString("ID")%>><input type="submit" value="删除"></form><%}%></p></div>
<p class="STYLE1"> <img src="images/fenge.gif" height="1" width="200"></p>
<%}}catch(Exception e){} %>
</body>

</html>


servlet代码
package com.servlets;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class ShowPage extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

int page = Integer.parseInt(request.getParameter("page"));
ServletContext context = request.getServletContext();
Statement stmt = (Statement) context.getAttribute("stmt");

ResultSet rs=null;
try{
String query = "SELECT * FROM wordsdetails ORDER BY speakdate DESC LIMIT 10 OFFSET " + (page-1)*10;
rs= (ResultSet) stmt.executeQuery(query);

request.setAttribute("rs",rs);
RequestDispatcher view = request.getRequestDispatcher("index.jsp");
view.forward(request,response);

}catch(SQLException e){}


}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}


}
chuaizicai 2011-08-28
  • 打赏
  • 举报
回复
额。。。求所有代码,说了这么多,没有把代码全贴出来给力
算法导论 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 mylovetiantian 的回复:]
引用楼主 tian_et 的回复:
若有哪个高手给出解释,高分奉送。再加一个深深的鞠躬!

背景:当我学了点Java Web之后,也具备了数据库知识之后,就开始自作聪明了,我没有去了解那些主流框架是把获得数据库连接的代码写在哪里,而我心想,数据库操作的步骤无非就是获得Connection,再通过它创建Statement对象,然后再通过Statement对象进行execute、executeQ……
[/Quote]你没仔细看我的问题啊,虽然我写得太多,但真得没法缩减篇幅了。我在ServletContextListener里写了setAttribute("stmt",stmt);
mylovetiantian 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 tian_et 的回复:]
若有哪个高手给出解释,高分奉送。再加一个深深的鞠躬!

背景:当我学了点Java Web之后,也具备了数据库知识之后,就开始自作聪明了,我没有去了解那些主流框架是把获得数据库连接的代码写在哪里,而我心想,数据库操作的步骤无非就是获得Connection,再通过它创建Statement对象,然后再通过Statement对象进行execute、executeQuery等方法执行sql语句。所以我就……
[/Quote]
楼主有没有在getAttribute之前,进行setAttribute呢?如果没有只是在servlet中配置了,是没有用的!Application.getAtrribute是获取整个应用中的属性值,获取之前的前提是已经赋值了,就是setAtrribute,否则是没有办法获取的?

而下面你又下了重新注册驱动并且重新创建数据库连接的语句后而且statement对象也是重新被创建的并不是在servletContext中获取的,那么stmt对象自然是可以调用了,通常在页面显示结果集的时候在servlet中会这么写
String name;
String sex;
while(Users user:list){
name=user.getName();
sex=user.getSex();
}
request.setAtrribute("name",name);
request.setAtrribute("sex",sex);
request.getRequestDispatch("success.jsp").forwod(request,response);
这样写前台页面就可以接收到刚才存放到request的会话区间中的值了,前台页面使用EL表达式即可获得;
比如:${name}
再request.setAtrribute的时候最好赋值的是一个对象,比如说刚才查询的是一个User对象,那么把查询出来的对象直接赋值的request会话区间中,然后通过前台页面的for循环进行获取对象的每个属性值,通常是最佳的选择;
例如如下代码:
for(int i=0;i<user.size();i++){
<tr>
<td>${user.getName}</td>
<td>${user.getSex}</td>
</tr>
}
至于分页也是同样的道理,只要把值放到request会话区间中即可,当然application活着session等会话区间中也可,关键是看自己的应用!呵呵,自己就会这么点东西希望对楼主有用哈,如有错误还请指正!
算法导论 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 liyang1271989 的回复:]
Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。
Statement对象,用于执行不带参数的简单SQL语句。

上诉2句说明statement是不能像lz说的那样的,
在说数据库连接后 是要关闭的 ,要不你数据库就得挂了!

statement 垃圾回收机制自动回收的,不过还是手动关闭。


以上为……
[/Quote]
如果关闭,就不能正常显示主页内容,可是它显示了,只是点分页的时候不显示
算法导论 2011-08-28
  • 打赏
  • 举报
回复
如果关闭,就不能正常显示主页内容,可是它显示了,只是点分页的时候不显示
liyang1271989 2011-08-28
  • 打赏
  • 举报
回复
Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。
Statement对象,用于执行不带参数的简单SQL语句。

上诉2句说明statement是不能像lz说的那样的,
在说数据库连接后 是要关闭的 ,要不你数据库就得挂了!

statement 垃圾回收机制自动回收的,不过还是手动关闭。


以上为个人理解,请求指正
算法导论 2011-08-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 yangting_lisa 的回复:]
好长哇。。。lz你表述简单点吗嘛
[/Quote]已经是最简洁的表述了。因为这问题本来就蹊跷。不把前因后果都罗列出来,你们不能对症下药的
小笨熊 2011-08-28
  • 打赏
  • 举报
回复
好长哇。。。lz你表述简单点吗嘛

81,090

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧