沐风Cc 2019-04-24 15:44 采纳率: 100%
浏览 545
已采纳

连接池:为什么方法结束之后,连接池中所有链接都结束了???

1.问题:
我写了一个DBUtil 操作数据库基类,使用的时 druid连接池。


public class DBUtil {

    //省略其它代码

    //连接数据库的对象
    private Connection con ;
    //建立操作指令对象
    private PreparedStatement ps;
    //操作结果的对象
    private ResultSet rs;


    //创建 数据库对象,建立连接
    public void getCon() {
            try {
                // 连接池 操作
                Properties properties = new Properties();
                properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties"));
                DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
                con = dataSource.getConnection();

            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    //查
    public ResultSet query(String sql, Object[] obj){
        getCon();
        try {
            ps = con.prepareStatement(sql);
            for(int i = 0; i<obj.length; i++){
                 ps.setObject(i+1, obj[i]);
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;
    }

    public void close(){
        try {
            if(con != null){
                con.close();
            }
            if(ps != null){
                ps.close();
            }
            if(rs != null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

配置文件中:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/library?allowMultiQueries=true
username=root
password=123
minIdle=10
maxIdle=50
initialSize=3
maxActive=100
maxWait=100
removeAbandonedTimeout=180
removeAbandoned=true

当我写一个Test()方法测试的时候,发现连接池就会多次创建,并且当方法结束之后,连接池中又没有连接数了

    @Test
    public void show(){
        Object [] Object = {};
        DBUtil dbUtil = new DBUtil();
        long startTime=System.currentTimeMillis();   //获取开始时间
        ResultSet rs = null;
        for (int i = 0; i < 2; i++) {
            rs = dbUtil.query("select id from logtable", Object);
             dbUtil.close();
        }

        long endTime=System.currentTimeMillis(); //获取结束时间
        System.out.println("程序运行时间: "+(endTime-startTime)+"ms");
    }

详细如图:

图片说明

图片说明

图片说明

图片说明

图片说明

实在不清楚怎么回事,还请各位老哥 解惑! 谢谢


上一个问题,有了一点眉目,现在我又有些疑问了。

新的问题

现在又有一个问题
我把查询方法抽成了一个公共方法 ** query() 方法** :如

public class DBPoolConnection {
    private static ResultSet resultSet;
    private static DruidPooledConnection conn = null;
    private PreparedStatement ps = null;
    private static DBPoolConnection dbPoolConnection = null;
    private static DruidDataSource druidDataSource = null;

    static {
        Properties properties = new Properties();
        try {
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties"));
            druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);    //DruidDataSrouce工厂模式

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 数据库连接池单例
     * @return
     */
    public static synchronized DBPoolConnection getInstance(){
        if (null == dbPoolConnection){
            dbPoolConnection = new DBPoolConnection();
        }
        return dbPoolConnection;
    }

    /**
     * 返回druid数据库连接
     * @return
     * @throws SQLException
     */
    public DruidPooledConnection getConnection() throws SQLException {
        return druidDataSource.getConnection();
    }

    /**
     * @Description 查询的公共方法
     */ 
    public ResultSet query(String sql,Object [] objects){
        try {
            DBPoolConnection dbPoolConnection = DBPoolConnection.getInstance();
            conn = dbPoolConnection.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < objects.length; i++) {
                ps.setObject(i,objects[i]);
            }
            resultSet = ps.executeQuery();
        } catch (SQLException e) {
            System.out.println("有异常");
            e.printStackTrace();
        }finally {
            try {
                if (null != ps) {
                    ps.close();
                }
                if (null != conn) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return resultSet;
    }

}


当我写一个测试方法,如:

    @Test
    public void Test(){
        Object [] Object = {};
        DBPoolConnection dbPoolConnection = new DBPoolConnection();
        ResultSet rs = null;
        for (int i = 0; i < 2; i++) {
            rs = dbPoolConnection.query("select id from logtable", Object);
        }
        String id = "";
        if (null != rs) {
            try {
                if (rs.next()) {
                    rs.previous();
                    while (rs.next()){
                        id = rs.getString("id");
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (null != rs) {
                        rs.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
        }
        System.out.println("-------------获取数据:"+id);
    }

执行后就提示:

java.sql.SQLException: Operation not allowed after ResultSet closed
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
    at com.mysql.jdbc.ResultSet.checkClosed(ResultSet.java:666)
    at com.mysql.jdbc.ResultSet.next(ResultSet.java:7274)

图片说明

百度了一下,这个是因为提前关闭了连接。

那我就有疑问了,怎么才能抽成一个公共方法,当去调用这个公共方法时,不报这个异常,**这个怎么解决啊**,各位老哥

  • 写回答

5条回答 默认 最新

  • a718089112 2019-04-24 17:06
    关注

    你的DBUtil getCon() 方法有问题:DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

    这里的dataSource是数据源,不能重复生成的,只需要一个。把dataSource放到类的成员变量,使用static块获取dataSource

    参考:https://www.cnblogs.com/yulinfeng/p/5986395.html

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!