当前位置:编程学习 > JAVA >>

Connection关闭时报错

我想要写一个定时访问数据库,读取数据里的数据但是我没法关闭Connection链接,请问怎么解决?
下面是我代码
public class UploadFileDao {

        private Connection conn = null;
        private PreparedStatement pstmt = null;
        private ResultSet rs = null;

        public List<UploadFile> listUploadFile() {
                List<UploadFile> uploadFile_l = new ArrayList<UploadFile>();
                String sql = "select * from uploadfile";
                conn = DBConnection.getConn();
                pstmt = DBConnection.getPstmt(conn, sql);
                rs = DBConnection.getRest(pstmt);
                try {
                        while (rs.next()) {
                                UploadFile uploadFile = new UploadFile();
                                uploadFile.setId(rs.getInt("id"));
                                uploadFile.setFileUrl(rs.getString("file_Url"));
                                uploadFile.setStatus(rs.getInt("status"));
                                uploadFile_l.add(uploadFile);
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                } finally{
                        if(rs != null){
                                try {
                                        rs.close();
                                        rs = null;
                                } catch (SQLException e) {
                                        e.printStackTrace();
                                }
                        }
                        if(pstmt != null){
                                try {
                                        pstmt.close();
                                        pstmt = null;
                                } catch (SQLException e) {
                                        e.printStackTrace();
                                }
                        }
                        if(conn != null){
                                try {
                                        conn.close();
                                        conn = null;
                                } catch (SQLException e) {
                                        e.printStackTrace();
                                }
                        }
                }
                return uploadFile_l;
        }



public class ReadDB implements Runnable {

        public void run() {
                List<UploadFile> uploadFiles = new UploadFileDao().listUploadFile();
                System.out.println(uploadFiles.size());
        }

        public static void main(String[] args) {
                ReadDB readDB = new ReadDB();
                while (true) {
                        readDB.run();
                        try {
                                Thread.sleep(5000);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }
}

运行的时候报
com.mysql.jdbc.excepti**.MySQLNonTransientConnectionException: No operati** allowed after connection closed.
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:888)
        at com.mysql.jdbc.Connection.checkClosed(Connection.java:1931)
        at com.mysql.jdbc.Connection.prepareStatement(Connection.java:4705)
        at com.mysql.jdbc.Connection.prepareStatement(Connection.java:4671)
        at com.test.util.DBConnection.getPstmt(DBConnection.java:40)
        at com.test.dao.UploadFileDao.listUploadFile(UploadFileDao.java:23)
        at com.test.util.ReadDB.run(ReadDB.java:11)
        at com.test.util.ReadDB.main(ReadDB.java:18)
Exception in thread "main" java.lang.NullPointerException
        at com.test.util.DBConnection.getRest(DBConnection.java:50)
        at com.test.dao.UploadFileDao.listUploadFile(UploadFileDao.java:24)
        at com.test.util.ReadDB.run(ReadDB.java:11)
        at com.test.util.ReadDB.main(ReadDB.java:18)
说我的于数据库断开之后还进行数据库操作
但是如果不断开链接会导致内存泄露。。。

请问怎么解决? java --------------------编程问答-------------------- 多线程引起的吧。
其中一个线程把conection关闭了,另外一个线程想操作这个connection自然就报错了,楼主可以仔细看,报的是空指针异常,也就是conection已经为null了,然后你对他还有操作。 --------------------编程问答-------------------- 同步一下呗!!!! --------------------编程问答-------------------- 可以使用isClose来判断一下 --------------------编程问答--------------------
引用 3 楼 AWUSOFT 的回复:
可以使用isClose来判断一下

yes------ --------------------编程问答-------------------- 其他不想说,我只想问一句:
readDB.run();
这个位置确定是调用run()方法的吗?这么写不是多线程的吧? --------------------编程问答-------------------- 我数据库连接是读取properties配置文件读取的  。。
那的代码我就不粘贴了

下面是DBConnection的数据库连接类
public class DBConnection {

private static Connection conn = null;
private static final String filePath = "jdbc.properties";

private DBConnection() {
ReadProp readProp = new ReadProp(filePath);
String driver = readProp.retVal("driver");
String url = readProp.retVal("url");
String user = readProp.retVal("user");
String password = readProp.retVal("password");
try {
if (conn == null) {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}

public static Connection getConn() {
if (conn == null) {
new DBConnection();
}
return conn;
}

public static PreparedStatement prepareStatement(Connection conn, String sql) {
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pstmt;
}

public static ResultSet executeQuery(PreparedStatement pstmt) {
ResultSet rs = null;
try {
rs = pstmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}

public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
conn = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void close(PreparedStatement pstmt) {
if (pstmt != null) {
try {
pstmt.close();
pstmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}

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

public static void main(String[] args) {
System.out.println(DBConnection.getConn());
}
}

Dao 层

public class UploadFileDao {

private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;

public List<UploadFile> listUploadFile() {
String sql = "select * from uploadfile";
conn = DBConnection.getConn();
pstmt = DBConnection.prepareStatement(conn, sql);
rs = DBConnection.executeQuery(pstmt);
List<UploadFile> uploadFile_l = new ArrayList<UploadFile>();
try {
while (rs.next()) {
UploadFile uploadFile = new UploadFile();
uploadFile.setId(rs.getInt("id"));
uploadFile.setFileUrl(rs.getString("file_Url"));
uploadFile.setStatus(rs.getInt("status"));
uploadFile_l.add(uploadFile);
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
if(rs != null){
DBConnection.close(rs);
}
if(pstmt != null){
DBConnection.close(pstmt);
}
if(conn != null){
DBConnection.close(conn);
}
}
return uploadFile_l;
}

public static void main(String[] args) {
System.out.println(new UploadFileDao().listUploadFile());
}
}


Timer 层

public class Time extends TimerTask // 创建测试的类Time继承TimerTask,导入TimerTask包
{
private Timer timer = null;// 开始要将timer对象赋初值null
private long timestop = 5000;// 每隔5秒执行一次任务

public Time() {
timer = new Timer();
}

// 构造函数
private void Time() {
UploadFileDao uploadFileDao = new UploadFileDao();
List<UploadFile> uploadFile_l = uploadFileDao.listUploadFile();
for (UploadFile uploadFile : uploadFile_l) {
System.out.println(uploadFile.getFileUrl());
}
}

// 需要执行的任务,也就是定时需要执行的功能模块函数,都可以写在这个函数里面,当然函数名可以自己取。
public void test() {
Time t = new Time();
Date date = new Date();
timer.schedule(t, date, timestop);
}

// 真正启动任务的函数,当在main函数中new一个新对象时,调用此函数,在此函数中有schedule方法,启动任务。
public void run() {

this.Time();
}

public static void main(String[] args) {
Time t = new Time();// 创建对象实体
t.test();// 启动定时器任务
}
}

现在运行的时候还是报之前的错误,我知道是关闭了Connection后又调用了,但是现在我想定时读取数据库里的数据,必须再次调用啊。 这里该怎么解决呢? Connection总不能不关闭吧。 --------------------编程问答-------------------- 可不关啊,只使用一个连接,或者使用连接池....都是长连接的原理. --------------------编程问答--------------------
引用 7 楼 AWUSOFT 的回复:
可不关啊,只使用一个连接,或者使用连接池....都是长连接的原理.

写了一个功能,每次需要执行的时候才启动程序,用的是数据库连接池 。
我也不知道程序在哪里结束,
所以: 如何根据程序的结束来释放连接池里面的连接呢 --------------------编程问答-------------------- DBConnection

public static Connection getConn() {
if (conn == null) {
conn=new DBConnection();
}
return conn;
} --------------------编程问答--------------------
 if(rs != null){
                                try {
                                        rs.close();
                                        rs = null;
                                } catch (SQLException e) {
                                        e.printStackTrace();
                                }


rs = null;这条语句不要试试
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,