我用了tomcat内置的连接池,使用这个连接池的时候是否需要用一个单例模式管理呢?(如回复1所示)如果不用单例模式,而是每次使用的时候都初始化这个对象,这样就会造成系统里生成很多连接池?对吗?但是即使写成下面的样子,在每个jsp页面调用完这个bean后,所有用完的对象不是应该都销毁了吗?所以SSqlConn对象的连接池也该销毁了啊。总之,我总觉得下边的代码有问题,希望有人帮我改一下。
调试欢乐多
获取数据库链接的单例类public class SSqlConn
{
private Connection conn = null;
private static final SSqlConn sqlconn=null;
private DataSource=null; private SSqlConn()
{
try
{
Context ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/sqlserver");
}catch(Exception e)
{
e.printStackTrace();
}
} public static Connection getConn()
{
if(sqlconn==null)
{
sqlconn=new SSqlConn();
} conn = ds.getConnection();
return conn;
}
}调用数据库链接的代码public DBTest
{
private Statement stmt=null;
private ResultSet rs=null;
private Connection conn = null;//获取statement
public DBTest()
{
conn=SSqlConn.getConn();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
}//获取resultset
public ResultSet getResultset(String sql) throws SQLException
{
rs = stmt.executeQuery(sql);
return rs;
} public void dbClose()
{
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
}catch (SQLException e)
{
System.out.println(e);
}
}
}
static成员在全局栈空间内,不在heap,GC不起作用,只有进程消失JVM自己收回.这算是单例那个静态“自己”造成的
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Hashtable;import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;import org.apache.log4j.Logger;
/**
*
* @author Julie
* 通过weblogic/tomcat的方式获得数据源
* 最后关闭连接
*/
public class WebContext {
/*
* 创建Log
*/
private static Logger logger = Logger.getLogger(WebContext.class.getName()); private static DataSource ds = null; private static Context initContext = null; private static Context connContext = null;
/** tomcat 方式--------------------------------------------------*/
// static {
//// logger.info("开始连接...");
//// try {
//// connContext = new InitialContext();
//// // 初始化上下文
//// logger.info("connContext: " + connContext.toString());
//// envContext = (Context) connContext.lookup("java:/comp/env"); // 获取环境上下文
//// logger.info("envContext: " + envContext.toString());
//// ds = (DataSource) envContext.lookup("jdbc/zyx"); // 通过JNDI名字创建数据源
//// logger.info("数据源对象: " + ds);
//// } catch (NamingException e) {
//// // TODO Auto-generated catch block
//// e.printStackTrace();
//// }
// }
/** weblogic 方式------------------------------------------------*/
static {
logger.info("开始连接...");
try {
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
// 这里的IP地址是配置了数据源的weblogic的IP
ht.put(Context.PROVIDER_URL, "t3://10.222.18.149:7001");
initContext = new InitialContext(ht);
ds = (DataSource) initContext.lookup("jdbc/zyx");
logger.info("数据源对象: " + ds);
}
catch (NamingException e) {
e.printStackTrace();
logger.error("---------error----", e);
}
} public static DataSource getDataSource() {
if (ds == null) {
//重新为DataSource赋值,获取数据源
new WebContext();
}
return ds;
}
//获得Connection连接
public static Connection getDBConnection() {
Connection conn = null; try {
if (ds == null) {
new WebContext();
} conn = ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
} /*
* 关闭数据库连接对象
*/
public void connClose(Connection conn) {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (Exception e) {
logger.info(e.getMessage());
}
}
/*
* 本地测试使用的数据库连接池方式进行连接
public static Connection getConnection() throws SQLException{
Connection conn = null ;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@10.203.4.5:1521:zyxdb","zylife","zylife");
}catch(SQLException e){
e.printStackTrace();
}
catch(Exception ex){
ex.printStackTrace();
}
return conn;
}
*/
}
ConnectionDAO.javaimport java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import javax.sql.DataSource;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;import com.cpic.zyx.util.context.WebContext;
/**
*
* @author Julie and ChenMingYong
* 通过WebContext获取数据源的链接
* 打开链接,并处理和数据资源有关的关闭处理
*/
public class ConnectionDAO { private static final Log logger = LogFactory.getLog(ConnectionDAO.class); private DataSource ds =null;
/**
* 实例化一个DataSource对象
*
*/
public ConnectionDAO(){
this.ds = WebContext.getDataSource();
}
/**
* @return
* @throws SQLException
* 获得一个Connection连接
*/
public Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* Close the given JDBC Connection and ignore any thrown exception.
* This is useful for typical finally blocks in manual JDBC code.
* @param con the JDBC Connection to close
*/
public void closeConnection(Connection con) {
if (con != null) {
try {
con.close();
} catch (SQLException ex) {
logger.error("Could not close JDBC Connection", ex);
} catch (Throwable ex) {
// We don't trust the JDBC driver: It might throw RuntimeException or Error.
logger.error("Unexpected exception on closing JDBC Connection",
ex);
}
}
} /**
* Close the given JDBC Statement and ignore any thrown exception.
* This is useful for typical finally blocks in manual JDBC code.
* @param stmt the JDBC Statement to close
*/
public void closeStatement(Statement stmt) {
if (stmt != null) {
try {
// stmt.cancel();
// stmt.close();
stmt.close();
} catch (SQLException ex) {
logger.warn("Could not close JDBC Statement", ex);
} catch (Throwable ex) {
// We don't trust the JDBC driver: It might throw RuntimeException or Error.
logger.error("Unexpected exception on closing JDBC Statement",
ex);
}
}
} /**
* Close the given JDBC ResultSet and ignore any thrown exception.
* This is useful for typical finally blocks in manual JDBC code.
* @param rs the JDBC ResultSet to close
*/
public void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
logger.warn("Could not close JDBC ResultSet", ex);
} catch (Throwable ex) {
// We don't trust the JDBC driver: It might throw RuntimeException or Error.
logger.error("Unexpected exception on closing JDBC ResultSet",ex);
}
}
}
}
[email protected]
670200556
static成员在全局栈空间内,不在heap,GC不起作用,只有进程消失JVM自己收回.这算是单例那个静态“自己”造成的
在某个链接数据库的bean使用完毕后,它涉及的对象不是应该都销毁吗?所以SSqlConn对象建立的连接池也该销毁了。
每个用户都要使用这个bean,每次使用都生成一个有10个链接的连接池。
这岂不是比直接连数据库更耗资源么?
的确应该是这样,我想问在底层怎么操作的呢?
“连接池不会销毁”,连接池也只是一个类而已,它用什么机制阻止被销毁呢?
“SSqlConn是针对所有用户建立的连接池,不是针对某一个用户”,哪个地方做的这个保证呢?
如果用单例的话,应该不能把connection设为类成员吧,否则不就成了大家共享同一个connection了