mufeng633
沐风Cc
采纳率73.7%
2019-04-25 10:46 阅读 528

JDBC 如何抽成一个公共查询方法,并正确释放资源 close()

10

1.描述问题

将查询数据库操作,抽成一个公共方法,如下:

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)

图片说明

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

问:

怎么才能抽成一个公共方法,当在其它类中去调用 query() 这个公共方法时,不报这个异常... 并正确释放资源呢

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • weixin_39606236 ꧁gaoKuo꧂ 2019-04-25 11:45

    这个看起来是close顺序有问题把,

    把这段代码先注掉试一下

    try {
                    if (null != ps) {
                        ps.close();
                    }
                    if (null != conn) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
    

    写一个类,持有resultSet,conn,ps三个对象
    query方法返回这个类的实例
    这个类中定义方法close 关闭三个对象

    点赞 评论 复制链接分享
  • qq_27718453 庄粟 2019-04-25 18:19

    不建议返回resultSet来操作,操作它还要处理相关的异常。最终只是要返回的数据,query直接提取数据然后返回你封装的数据就好了,也可以返回Map比较方便。

    点赞 评论 复制链接分享

相关推荐