我用了tomcat内置的连接池,使用这个连接池的时候是否需要用一个单例模式管理呢?(如回复1所示)如果不用单例模式,而是每次使用的时候都初始化这个对象,这样就会造成系统里生成很多连接池?对吗?但是即使写成下面的样子,在每个jsp页面调用完这个bean后,所有用完的对象不是应该都销毁了吗?所以SSqlConn对象的连接池也该销毁了啊。总之,我总觉得下边的代码有问题,希望有人帮我改一下。

解决方案 »

  1.   

    下面的大部分的核心代码:
    获取数据库链接的单例类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); 
                 }
    }
    }
      

  2.   

    我觉得,这得看具体要求,比如可以一个连接池getConn()100次,也可以是有20个连接池实例,每个连接池可能会连数据库5次。如果连接数很多,或许应该用多个连接池。
    static成员在全局栈空间内,不在heap,GC不起作用,只有进程消失JVM自己收回.这算是单例那个静态“自己”造成的
      

  3.   

    WebContext.javaimport java.sql.Connection;
    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);
    }
    }
    }
    }
      

  4.   

    我有一个关于这方面的视频,需要的话我可以给你
    [email protected]
    670200556
      

  5.   

    我觉得,这得看具体要求,比如可以一个连接池getConn()100次,也可以是有20个连接池实例,每个连接池可能会连数据库5次。如果连接数很多,或许应该用多个连接池。 
    static成员在全局栈空间内,不在heap,GC不起作用,只有进程消失JVM自己收回.这算是单例那个静态“自己”造成的
      

  6.   

    我的困惑主要是:(比较菜啊)
    在某个链接数据库的bean使用完毕后,它涉及的对象不是应该都销毁吗?所以SSqlConn对象建立的连接池也该销毁了。
    每个用户都要使用这个bean,每次使用都生成一个有10个链接的连接池。
    这岂不是比直接连数据库更耗资源么?
      

  7.   

    连接池不会销毁,连接池始终维护一定数量的连接,有用户需求的时候调用,使用完就放回连接池等着其它用户调用,SSqlConn是针对所有用户建立的连接池,不是针对某一个用户
      

  8.   


    的确应该是这样,我想问在底层怎么操作的呢?
    “连接池不会销毁”,连接池也只是一个类而已,它用什么机制阻止被销毁呢?
    “SSqlConn是针对所有用户建立的连接池,不是针对某一个用户”,哪个地方做的这个保证呢?
      

  9.   

    如果不用单例的话,你可以在页面上把javaBean的scope设为application,这样大家在整个web应用中共享同一个Javabean对象实例。
    如果用单例的话,应该不能把connection设为类成员吧,否则不就成了大家共享同一个connection了