jsp+tomcat+mysql数据库连接池总算配置成功了,但具体用法还有些不清楚,请教各位!
此贴接自http://community.csdn.net/Expert/topic/3667/3667085.xml?temp=.4318201
首先感谢hfree()的详细解答,也谢谢所有的参于者,希望各位能接着指点小弟一二。
接下来的问题是怎样应用我的连接池
按照hfree()的方法我建立了一个DBConnection.java:
package japhone.utile;
import java.sql.* ;
import javax.naming.* ;
import javax.sql.DataSource ;
public class DBConnection {
public static synchronized Connection getConnection() throws java.lang.Exception
{
try{
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
return ds.getConnection() ;
}
catch(java.sql.SQLException e) {throw e ;}
catch(javax.naming.NamingException e) {throw e; }
}
}
然后做了一个JSP文件test1.jsp
如下:
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.sql.*" %>
<html>
<head>
<title>test</title>
</head>
<jsp:useBean id="DBCnn" scope="page" class="japhone.utile.DBConnection" />
<body>
<%
Connection conn=DBCnn.getConnection();
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from file";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
out.println(rs.getString("fname"));
out.println("<br>");
}
%>
</body>
</html>
测试成功,没有问题,也可以从数据库中读出数据。
现在问题是,我不知道是不是这样就算是调用连接池了?如果我再写别的查询语句的时候,是不是继续这样写下去:
Connection conn=DBCnn.getConnection();
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql1="select * from user";
ResultSet rs1=stmt.executeQuery(sql1);
Connection conn=DBCnn.getConnection();
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql2="select * from news";
ResultSet rs2=stmt.executeQuery(sql2);
…………
…………
而且不用调用rs.close()关闭数据库?
哎,现在头脑乱乱的,也不知大家能否理解我想说什么?
希望大家帮忙!感谢!
问题点数:100、回复次数:31Top
1 楼robber(海盗)回复于 2004-12-23 14:38:03 得分 2
关键是调用Connection的close()才可以回收资源。
rs一般可以调用close()也可以不用调用。而且要使用finnally保证一定执行close语句。Top
2 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 14:54:09 得分 0
关闭先不要讲了,我也不明白,
我现在最关心的是创建的时候,是不是每次都要写如下语句?
String sql1="select * from user";
ResultSet rs1=stmt.executeQuery(sql1);
String sql2="select * from news";
ResultSet rs2=stmt.executeQuery(sql2);
…………
…………
如果是这样,那么有的资料上不是说在连接池中,已经有许多空闲的连接了吗?
为什么还要反复定义resultset?
Top
3 楼viano(优秀是一种习惯!)回复于 2004-12-23 15:01:14 得分 2
stmt.executeQuery(sql)
表示 使用 数据对象 stmt 执行 sql 语句
连接池 只创建 连接没有执行sql 语句, 自然每次都要 stmt.executeQuery(sql);
了!Top
4 楼viano(优秀是一种习惯!)回复于 2004-12-23 15:04:00 得分 10
每次 只用 datasource 对象时, 我们从连接池取出一个连接, 如果连接池没有可用的连接
则会等待。
当使用完后 我们 close() 则会把连接 还给连接池 而不是 数据库!
在一个java 文件众,你可以定义 一个 ResulteSet !
Top
5 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 15:07:04 得分 0
to: viano(有心就有翼,我想我能.......)
也就是说写了DBConnection.java后
每次我执行ResultSet rs=stmt.executeQuery(sql);
就算是在调用连接池了?
是不是这样?Top
6 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 15:12:24 得分 0
to: viano(有心就有翼,我想我能.......)
当使用完后 我们 close() 则会把连接 还给连接池 而不是 数据库
//这句话意思是不是说,在每次调用rs后,可以使用rs.close()?
在一个java 文件众,你可以定义 一个 ResulteSet
//这句话意思是不是说,为了便利,我还需要再写一个JAVA文件,来写统一的resultset 以便调用?类似代码如下:
public ResultSet executeQuery(String sql)
{
conn=null;
rs=null;
try
{
conn=DBConnection getConnection();
Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs=stmt.executeQuery(sql);
}
catch(Exception e)
{
System.out.println("MySQL:"+e.getMessage());
System.out.println("MySQL:"+sql);
}
return rs;
}
是不是这样?Top
7 楼viano(优秀是一种习惯!)回复于 2004-12-23 15:20:03 得分 6
1.
不是!
2.
你的连接池是用的 tomcat 的。 那么你每次 根据
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
return ds.getConnection() ;
生成的连接对象要是调用了 close() 方法则会将连接还给连接池(tomcat的连接池)
!
关于ResultSet 你的理解是不对的。
ResultSet 是我们将 结果集保存起来 使用的!
这个 和具体的连接池 没有什么关系。
如果你的 sql 语句不得到 结果集的话 可以不使用 ResultSet
例如 插入语句!
Top
8 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 15:25:07 得分 0
噢,第二个我好像明白了,那第一个呢?
我在用完rs后,到底该不该写rs.close()呢?Top
9 楼viano(优秀是一种习惯!)回复于 2004-12-23 15:34:45 得分 2
当然要写了, 把资源归还给系统!Top
10 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 15:52:21 得分 0
总结一下:
//DBConnection.java
package japhone.utile;
import java.sql.* ;
import javax.naming.* ;
import javax.sql.DataSource ;
public class DBConnection {
public static synchronized Connection getConnection() throws java.lang.Exception
{
try{
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
return ds.getConnection() ;
}
catch(java.sql.SQLException e) {throw e ;}
catch(javax.naming.NamingException e) {throw e; }
}
}
是不是每次我调用DBConnection.getConnection()建立连接的时候就是调用了连接池?也提高了系统的性能?Top
11 楼hfree()回复于 2004-12-23 16:18:40 得分 20
是不是每次我调用DBConnection.getConnection()建立连接的时候就是调用了连接池?也提高了系统的性能?
.......................
不能说是调用连接池 . 应该是说,你在Tomcat里面配置了一个连接池,然后你用DBConnection.getConnection()方法从连接池中获得一个连接,然后你用这个连接Connection创建Statement,执行Query,Update之类的操作.但是要记住一点是,连接池里面已经配置了一定数量的数据库连接,看server.xml里面的这一句.
<!-- 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>100</value>
</parameter>
这里,配置的最大连接数是100个连接,当你用DBConnection.getConnection()取得一个连接之后,池里面就少了一个连接.如果你只是取,还不归还连接( 可以Connection.close() ) ,就会导至池里面的连接不断减少乃至到最后为0,也就是没有可用的连接啦.所以每次用完之后都要用Connection.close()还归还.当然,在这里也有一个与平时不同的地方.就是Connection.close(),因为现在是从连接池里面取得连接的,所以调用Connection.close()并不是真的关闭这一个连接,而是把这一个连接放回连接池里面.如果Connection不是从池里面取得的,而是通过一般直接连接数据库取得的话,那样Connection.close()就会关掉这一个连接.
Top
12 楼drugon(更高,更远,更强)回复于 2004-12-23 16:24:54 得分 6
最关键的是数据库的Connection用后要关,不然访问量比较大的时候系统会死掉的,其它的几个可以不关。
在连接池中你用con.close()其它也没有真正的把这个Connection关掉,因为中间有一个连接池,它看到你做这个操作时,只是把你的Connection回收回来,并没有真正的关掉,还可以利用的。Top
13 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 16:37:18 得分 0
to:hfree()
我终于明白了
能不能再帮我解释以下几个语句分别定义什么?
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
Top
14 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 16:40:38 得分 0
to:hfree() drugon(personal)
二位的Connection.close()和con.close()指的可是rs.close()?Top
15 楼hfree()回复于 2004-12-23 16:46:16 得分 6
能不能再帮我解释以下几个语句分别定义什么?
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
....................................................................
javax.sql.DataSource ds = (DataSource)envCtx.lookup("jdbc/bbs") ;
这一句,参考前面的配置
<Resource name="jdbc/bbs" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/bbs">
因为这里是"jdbc/bbs",所以才会有上面查找那句lookup("jdbc/bbs")
至于这两句
javax.naming.Context initCtx = new javax.naming.InitialContext() ;
javax.naming.Context envCtx = (Context)initCtx.lookup("java:comp/env") ;
呵呵,我也不太清楚.大概就是初始化上下文.然后从java:comp/env这一个查找一个环境变量!
格式都是照套的.我写这一段代码的时候都是ctrl+c , ctrl+v的,呵呵,大家不要笑我!所以我也不是太了解这一段的机制!大概要用到JNDI的知识吧.学习中!...........Top
16 楼hfree()回复于 2004-12-23 16:48:49 得分 10
二位的Connection.close()和con.close()指的可是rs.close()?
晕.!
你似乎没有弄懂Connection和ResultSet!
Connection是数据库的一个连接,利用这一个连接,你可以创建Statement!
而ResultSet只是一个查询数据库后返回的结果集,可以由Statement.executeQuery()返回!ResultSet.close关闭的只是这一个结果集,而不是关闭数据库连接!
也就是说Connection.close和ResultSet.close是不同的.Top
17 楼robber(海盗)回复于 2004-12-23 16:57:35 得分 1
楼主的基础还要再加强啊!否则交流困难啊...Top
18 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 17:29:03 得分 0
to: hfree()
Connection是数据库的一个连接,利用这一个连接,你可以创建Statement!
而ResultSet只是一个查询数据库后返回的结果集,可以由Statement.executeQuery()返回!ResultSet.close关闭的只是这一个结果集,而不是关闭数据库连接!
===========================================================================
rs.close()的调用我会,那么Connection.close()在什么情况下能用到呢?Top
19 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 17:30:23 得分 0
to:robber(海盗)
JAVA真是太复杂了Top
20 楼blz(低头需要勇气,抬头需要实力)回复于 2004-12-23 17:32:43 得分 1
楼主加油啊Top
21 楼viano(优秀是一种习惯!)回复于 2004-12-23 17:35:22 得分 1
建议 楼主 先不要使用 连接池
自己 写一些 程序
增加基础!Top
22 楼hfree()回复于 2004-12-23 17:35:36 得分 20
rs.close()的调用我会,那么Connection.close()在什么情况下能用到呢?
===========================================================================
你从连接池里面取了一个Connection,利用这个Connection,你就可以进行数据库操作.当你的数据库操作完成后,就调用connection.close(),把这一个Connection放回连接池里.
比如说,有一个登陆验证界面.当用户输入username和password的时候,你就要进行数据库查询验证!
这时,你从连接池取得一个连接Connection conn = DBConnection.getConnection(),然后用这一个数据库的连接conn,你可以建立Statement,查询数据库以进行验证用户输入的username 和 password!
当这一个数据库操作任务完成之后,你就可以conn.close()啦,把这一个连接放回连接池,以供其他程序使用.
Top
23 楼hfree()回复于 2004-12-23 17:38:25 得分 2
至于你的这一个问题
我现在最关心的是创建的时候,是不是每次都要写如下语句?
String sql1="select * from user";
ResultSet rs1=stmt.executeQuery(sql1);
String sql2="select * from news";
ResultSet rs2=stmt.executeQuery(sql2);
...........................................................
一开始的时候,这样写无妨,随着学习深入你就会发现可以用DAO或是其他方法封装这一些数据库操作.
现在每次写也无妨!毕竟这是一个过程,大家都是这样过来的!Top
24 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 17:47:11 得分 0
to:viano(有心就有翼,我想我能.......)
做过一个JSP网站:www.wxgzcn.com
但不知是服务器不稳定还是什么问题,网页有时正常,有时提示错误,不知道什么原因。
向服务商查明原因,他则问我使用了连接池没有,我当然没有,然后他就避而不答,到现在我也没找到原因是什么,所以我现在想用连接池,看看是否还能出错。
具体情况请看我的网站吧www.wxgzcn.com,如果显示正常,你就使劲刷新,我保证,最多五六次就出错了,如果可以,顺便帮我分析一下这种情况的原因何在?是不是与连接池有关?还是其它原因?Top
25 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 17:49:04 得分 0
to: hfree()
不好意思,又有点糊涂啦
-------当这一个数据库操作任务完成之后,你就可以conn.close()-------
用了conn.close()后,rs.close()还要用吗?
还是混用?
………
rs.close();
conn.close();
…………
象上面这样?Top
26 楼hfree()回复于 2004-12-23 17:52:07 得分 4
正常的用法是
try {
conn.close() ;
stmt.close() ;
rs.close() ;
}
catch( SQLException e )
{e.println.....() ; }Top
27 楼hfree()回复于 2004-12-23 17:54:13 得分 1
to japhone:
强人啊.哎,亏我还帮人解答问题啊,自己连个网站都没弄过.Top
28 楼poppop(光盘)回复于 2004-12-23 17:55:20 得分 6
数据库连接池(Connection Pool)——大盒子
数据库连接(Connection)——餐刀
圣诞节你订购了100把餐刀用来开party,客人想用就到大盒子(开始盒子里只放了50把)里拿,佣人将用完的餐刀清洗后放回盒子。party开刀一半盒子空了,这时你又让人马上送了50把餐刀;没想到一会又没有,这时还有相当多的客人等着用,等你急急忙忙一查,原来佣人偷懒没有把餐刀放回盒子。这时你想说赶快洗(close Resultset)放回去(close Connection)!
Merry Xmas!
Top
29 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 18:08:01 得分 0
to: hfree()
先谢谢你耐心的回答
“强人啊.哎,亏我还帮人解答问题啊,自己连个网站都没弄过”
你这样说,我可真是有点不好意思了,小打小闹的弄个网站算不了什么,其实做网站的真正目的就是为了练jsp,呵呵!Top
30 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 18:08:45 得分 0
to:poppop(光盘)
你的比喻很有意思,谢谢你,我明白了:)Top
31 楼japhone(【无缘何生斯事,有情所累此身】)回复于 2004-12-23 18:23:08 得分 0
好了,最基本的问题我想我已明白了
我先练习一下,然后再开贴问更深层次的问题
谢谢大家的耐心解答,特别感谢hfree()
结贴!Top





