关于servlet的一点小疑问

在servlet中的init()建立数据库连接,在多人同时访问这个servlet时,他们是使用的同一个连接吗?如果是,这样做会出现问题吗?

你只要清楚一点:你得到的连接(无论是以什么方式)只是一个物理连接的“句柄”,你所有的操作只是通过这个“句柄”去操作那个jdbc Connection对象---
并且在servlet的业务方法中调用完JDBC以后,你肯定要去关闭那个刚刚操作过的jdbc Connection----所以,每个客户端得到的并不是同一个连接。

一般更通用的做法是:写一个专门负责数据库连接生成与释放的java Class,在servlet中就可以将这个Class import进来,直接调用其方法即可。

我在int()中建立连接,而在destory()中释放连接,由于destory()等到服务关闭才调用 ,所以我觉得多用户同时访问时应该用的是一个连接吧!同时访问时,会遇到问题吗?

提供一验证登录的 servlet 程序,供楼主参考:


package com.panabia.servlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import com.panabia.db.SQLFactory;

public class Login extends HttpServlet
{
SQLFactory SQL=new SQLFactory();//创建数据库连接类

public void init(ServletConfig config) throws ServletException
{super.init(config);}

public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
{
response.reset();
response.setContentType(
"text/html;charset=gb2312");
PrintWriter out=response.getWriter();
HttpSession session=request.getSession(true);

Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;

out.print(
"<html><title>java servlet</title><link rel=stylesheet href=/Apps/images/css.css/><body topmargin=100><center>");
//Start to process.
String username=request.getParameter(
"username");
if(username==null)username=
"$";
String password=request.getParameter(
"password");
if(password==null)password=
"$";
String inputcode=request.getParameter(
"inputcode");
if(inputcode==null)inputcode=
"$";

String sessioncode=(String)session.getAttribute(
"rand");
if(sessioncode==null)sessioncode=
"#";

if(!username.startsWith(
"$")&&!password.startsWith("$"))
{
if(!inputcode.equals(sessioncode)){
out.print(
"<script language=javascript>window.alert('您输入的验证码错误,请重试!');</script>");
out.print(
"<a href='/Apps/portal.htm' class='slink'>返回登录</a>");
out.print(
"<br>"+"<font color=#666666 size=1 face=arial>try again please</font>");
}
else{

try{
con=SQL.gainConnection();
ps=con.prepareStatement(
"select * from AppsUsers where username=?");
ps.setString(1,username);
rs=ps.executeQuery();
if(rs.next())
{
String p=rs.getString(
"password");
String u=rs.getString(
"username");
String role=rs.getString(
"role");
if(username.equals(u)&&password.equals(p)){
session.setAttribute(
"status","ok");
session.setAttribute(
"role",role);

response.sendRedirect(response.encodeRedirectURL(
"/Apps/main.jsp"));
}
else{out.print(
"<script language=javascript>window.alert('您输入的密码错误,请重试!');</script>");
out.print(
"<a href='/Apps/portal.htm' class='slink'>重新登录</a>");
out.print(
"<br>"+"<font color=#666666 size=1 face=arial>try again please</font>");
}
}
else{out.print(
"<script language=javascript>window.alert('无效的系统帐户,请重试!');</script>");
out.print(
"<a href='/Apps/portal.htm' class='slink'>返回登录</a>");
out.print(
"<br>"+"<font color=#666666 size=1 face=arial>try again please</font>");
}

}
catch(SQLException e){out.print(
"SQL error:"+e);}
finally{SQL.releaseConnection(rs,ps,null,con); }
//在业务方法中关闭数据库连接
}

out.print(
"</center></body></html>");
out.close();
}
}

public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
{
doPost(request,response);
}

public void destroy(){super.destroy(); if(SQL!=null) SQL=null;}
//在destroy();方法中清空SQL 句柄--
}

谢谢

这个类本身设计的很糟糕。

juniper解释是有道理的,但是juniper的例子好像和楼主的要求“init()建立数据库连接”有些不一致。juniper的例子的数据库连接是在dopost中生成,如果将Connection con=null成为类变量,在init方法中获得con,那么在doPost使用con时,将会是同一个连接了。

就思路上而言,你还是用juniper的例子吧,最好放弃你在“init()建立数据库连接,将Connection con=null成为类变量”。

我在int()中建立连接,而在destory()中释放连接,由于destory()等到服务关闭才调用 ,所以我觉得多用户同时访问时应该用的是一个连接吧!同时访问时,会遇到问题吗?


???

一个用户启动一个Servlet线程哪!
那么变量呢?


真是个SB问题!

在init()里得到的Connection不通过类变量能被doPost()用吗?
使用ThreadLocal不就可以了?

不一定啊
[该贴被xfzhu2003于2007-12-20 22:34修改过]