经过测试,《SIAS绩效考核管理系统》基本可以使用,可是一直令我不能安心的是硬连接数据库,每个用户查询一次都学要new 一个conn,直接读写物理数据,迟早会要出问题的,迟早的事反正都要干的,而且这样的代码被人看见会被鄙视的,于是我下定决心,要将配置数据库联接池在今晚拿下
Tomcat 提供了一个与Java Enterprise Edition应用服务相兼容的JNDI--InitialContext实现实例。它的初始数据设置在$CATALINA_HOME/conf/server.xml文件里,并可能在网页应用环境描述(/WEB-INF/web.xml)里被下列元素引用:
1) <env-entry>--环境入口,设置应用程序如何操作。
2) <resource-ref>--资源参数,一般是数据库驱动程序、JavaMail Session、自定义类工厂等。
3) <resource-env-ref>--在Servlet 2.4里用来简化设置不需认证信息的资源资源如环境参数、resource-ref变量。
InitialContext在网页应用程序初始化时被设置,用来支持网页应用程序组件。所有的入口和资源都放在JNDI命名空间里的java:comp/env段里。
设置JNDI资源
设置JNDI资源要在$CATALINA_HOME/conf/server.xml文件里使用下列标志符:
1) <Environment>--设置域个可变的JNDI InitialContext入口的名字和值(同上面说的<env-entry>等价)。
2) <Resource>--设置应用程序可用的资源的名字和类型(同上面说的<resource-ref>等价)。
3) <ResourceParams>--设置Java资源类工厂的名称或将用的JavaBean属性。
4) <ResourceLink>--给全局JNDI环境(JNDI Context)添加一个链接。
上述这些标志符必须放在<Context>和</Context>之间(针对专门的网页应用程序)或<DefaultContext>和</DefaultContext>之间。
此外,设在网页应用环境描述(Web Application Descriptor)(/WEB-INF/web.xml)里的名字和值也在初始环境(Initial Context)里被设置,当被<Environemt>元素值允许时将被重设初始值。
全局变量能在<Server>子元素的<GlobalNamingResources>里设置。
数据库连接池概述:
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素:
1) 最小连接数是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费;
2) 最大连接数是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
3) 如果最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
配置Tomcat数据库连接池的前提:
1. 必须装有Java运行环境;
2. 必须有SQL Server2000数据库服务器(可以不在本地);
3. 必须有jtds.jar,并将它放在$CATALINA_HOME/common/lib目录下(只能是这里)。使用它是因为Microsoft公司的Java SQL Server驱动程序不支持二次查询,我使用的是jtds-1.2.jar。(下载地址:http://sourceforge.net/project/showfiles.php?group_id=33291&package_id=25350&release_id=369359)
在$CATALINA_HOME/conf/server.xml里设置数据库连接池
首先配置tomacathome/confg下的server.xml文件
需要在<host></host>之间加上如下配置:
<Context path="/mssion" docBase="mssion"
debug="5" reloadable="true" crossContext="true"> <!--在我的工程目录下(mssion) -->
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_mssion_log." suffix=".txt"
timestamp="true"/> <!--设置Log文件 -->
<Resource name="jdbc/mssion"
auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/mssion">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<!-- Maximum number of dB connections in pool. Make sure you
configure your mysqld max_connections large enough to handle
all of your db connections. Set to 0 for no limit.
-->
<parameter>
<name>maxActive</name>
<value>600</value>
</parameter>
<!-- Maximum number of idle dB connections to retain in pool.
Set to 0 for no limit.
-->
<parameter>
<name>maxIdle</name>
<value>100</value>
</parameter>
<!-- Maximum time to wait for a dB connection to become available
in ms, in this example 10 seconds. An Exception is thrown if
this timeout is exceeded. Set to -1 to wait indefinitely.
-->
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<!-- MSSQLserver dB username and password for dB connections -->
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value>19851022</value>
</parameter>
<!-- Class name for mssqlserver JDBC driver -->
<parameter>
<name>driverClassName</name>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</parameter>
<!-- The JDBC connection url for connecting to your mssqlserver dB.-->
<parameter>
<name>url</name>
<value>jdbc:microsoft:sqlserver://localhost:1433;databasename=exam</value> <!--"Exam"is my DatabaseName-->
</parameter>
</ResourceParams>
</Context>
随后还要配置工程目录(mssion)下的web.xml文件( WEB-INFO下)
<resource-ref>
<description>MSSION DB user POOL </description>
<res-ref-name>jdbc/mssion</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<!-- Database Config end -->
现在环境大功告成了,下面来测试下
这个是我的数据库操作类
package Database;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import javax.naming.*;
public class conDB
{
Context ctx=null;
Connection cnn=null;
Statement stmt=null;
ResultSet rs=null;
//构造函数中初始化参数
public conDB()
{
try
{
ctx= new InitialContext();
if(ctx==null)
throw new Exception("mei you pei zhi huan jing!");
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mssion");
if (ds==null)
throw new Exception("mei you pei zhi shu jv ku!");
//Class.forName(driver);
System.out.println("-------使用缓冲池获取DS成功!");
cnn = ds.getConnection();
// cnn = ds.getConnection();
stmt = cnn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
// con=DriverManager.getConnection(url,user,pwd);
// stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
System.out.println("-------使用缓冲池获取stmt成功!");
}
catch(Exception exc1)
{
exc1.printStackTrace();
}
}
//数据查询方法
public ResultSet Query(String sql)
{
try
{
rs = stmt.executeQuery(sql);
}catch(SQLException sqle1)
{
sqle1.printStackTrace();
}
System.out.println("sql="+sql);
return rs;
}
//数据更新方法
public int Update(String sql)
{
int i=0;
try
{
i = stmt.executeUpdate(sql);
}catch(SQLException sql1)
{
sql1.printStackTrace();
}
System.out.println("sql="+sql);
return i;
}
//单独关闭ResultSet的方法
public void rsClose()
{
try
{
rs.close();
}catch(Exception exc1)
{
System.out.println("There's some exception happend while rs closed!");
}
System.out.println("--ResultSet has been closed!");
}
//关闭数据库连接
public void Close()
{
try
{
if(rs!=null)
{
rs.close();
}
if(stmt!=null)
{
stmt.close();
}
if(cnn !=null)
{
cnn.close();
cnn=null;
}
}catch(SQLException sqle2)
{
sqle2.printStackTrace();
}
System.out.println();
System.out.println("---Database has been closed!");
}
public String strCh(String str)
{
if(str==null)
{
str="";
}else{
try{
str=(new String(str.getBytes("iso-8859-1"),"gb2312")).trim();
}catch(Exception exc)
{
exc.printStackTrace();
}
}
return str;
}
}
以后无论在jsp页面还是在 servlet里面,只需倒入Database.conDB 即可方便的进行读写数据库
这是一个例子,用在我的用户登录及验证模块
package user;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import java.io.*;
import Database.conDB;
public class UserLoginDo extends HttpServlet
{
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
{
System.out.println("************************doGet!***");
response.setContentType("text/html;charset=GBK");
PrintWriter out=response.getWriter();
out.println("<html><head></head><body>");
int userID = 0;
String userAcc = request.getParameter("userAcc");//用户名,从表单获得
String userPwd = request.getParameter("userPwd");//密码,从表单获得
String userName = "";//真实姓名
String userPost = "";//用户的权限,如"管理员"将来在网页上显示
int DeptID=0;
String userDept = "";//用户所在部门
String userLevel = "";//用户级别
int can = 0;//是否参加考核
int isDemo = 0; //是否民主评议
ResultSet rs = null;
conDB db = new conDB();
String url =null;
boolean success = true;
if(userAcc==null||userPwd=="")
{
out.println("<script>alert('用户名或密码不能为空!');window.location.href='userlogin.jsp';</script>");
System.out.println("一用户登录失败");
return;
}
String sql = "select * from users where userAcc='"+userAcc+"' and userPwd='"+userPwd+"'";
try
{
rs=db.Query(sql);
if(!rs.next())
{
success = false;
//判断该用户名和密码是否存在或正确
out.println("<script>alert('用户名或密码错误或该用户不存在!请重新登录!');history.back(-1);</script>");
//System.out.println("一用户登录失败");
}
else
{
System.out.println("*******开始获得用户信息!");
userID = rs.getInt("userID");
userName = rs.getString("username");
userPost = rs.getString("userPost");
DeptID = rs.getInt("deptID");
userDept = rs.getString("userDept");
userLevel = rs.getString("userLevel");
can = rs.getInt("can");
isDemo = rs.getInt("isDemo");
}
}catch(SQLException sqle)
{
sqle.printStackTrace();
}
if(success)
{
//HttpSession session = request.getSession();
request.getSession().setAttribute("userID",userID);
request.getSession().setAttribute("userAcc",userAcc);
request.getSession().setAttribute("userName",userName);
request.getSession().setAttribute("userPost",userPost);
request.getSession().setAttribute("DeptID",DeptID);
request.getSession().setAttribute("userDept",userDept);
request.getSession().setAttribute("userLevel",userLevel);
request.getSession().setAttribute("can",can);
request.getSession().setAttribute("isDemo",isDemo);
request.getSession().setAttribute("userPwd",userPwd);
System.out.println("用户"+userAcc+"登录成功");
System.out.println("用户信息成功写入session");
if(can == 0){
out.println("<script>alert('抱歉,您不能参与本次考核!');history.back(-1);</script>");
}
else{
response.sendRedirect("LoginSuc.jsp");
}
}//end if
//db.Close();
out.println("</body></html>");
}
/**
* method doPost
*/
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
{
doGet(request,response);
}
}
至于登录页面就不用写了吧?
代码写的比较菜,小弟初学没多久,请各位多多指教,千万不要笑话
大使馆馆长2007儿童节凌晨4:20