沐风Cc 2019-04-25 10:46 采纳率: 100%
浏览 573
已结题

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

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条回答 默认 最新

  • ꧁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 关闭三个对象

    评论

报告相同问题?

悬赏问题

  • ¥15 krpano-场景分组和自定义地图分组
  • ¥15 lammps Gpu加速出错
  • ¥15 关于PLUS模型中kapaa值的问题
  • ¥15 关于博途V17进行仿真时无法建立连接问题
  • ¥15 机器学习教材中的例题询问
  • ¥15 求.net core 几款免费的pdf编辑器
  • ¥15 为什么安装HCL 和virtualbox之后没有找到VirtualBoxHost-OnlyNetWork?
  • ¥15 C# P/Invoke的效率问题
  • ¥20 thinkphp适配人大金仓问题
  • ¥20 Oracle替换.dbf文件后无法连接,如何解决?(相关搜索:数据库|死循环)