public static Operater check(String name, String password) {
Operater operater=new Operater();//操作员信息对象
String sql = "select *  from tb_operator where name='" + name
+ "' and password='" + password + "'and admin=1";//查询字符串
ResultSet rs = Dao.executeQuery(sql);//执行查询
try {
while (rs.next()) {//如果查询到了记录
operater.setId(rs.getString("id"));//设置操作员编号
operater.setName(rs.getString("name"));//设置操作员用户名
operater.setGrade(rs.getString("admin"));//设置操作员等级
operater.setPassword(rs.getString("password"));//设置管理员密码
}
} catch (Exception e) {
e.printStackTrace();
}
Dao.close(); //关闭连接对象
return operater;//返回操作员信息对象
}第一次调用此方法没问题 可第二次就出现下面的问题com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: 
No operations allowed after connection closed这个问题怎么解决啊 只有把Dao.close();这个关闭Connection的方法去掉,可是这样好像也不对啊?
各位有没有碰到过类似的问题,有好的解决办法?

解决方案 »

  1.   

    这种问题只能查看Dao的源码才知道怎么回事
      

  2.   

    源码在这
    public class Dao {
    protected static String dbClassName = 
    "com.mysql.jdbc.Driver";//数据库连接驱动类
    protected static String dbUrl = "jdbc:mysql://localhost/db_library;";//数据库连接URL
    protected static String dbUser = "root"; //数据库用户名
    protected static String dbPwd = "admin"; //数据库密码
    private static Connection conn = null; //数据库连接对象
    private Dao() { //默认构造函数
    try {
    if (conn == null) { //如果连接对象为空
    Class.forName(dbClassName); //加载驱动类
    conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);//获得连接对象
    }
    } catch (Exception ee) {
    ee.printStackTrace();
    }
    }
    private static ResultSet executeQuery(String sql) { //查询方法
    try {
    if(conn==null)  new Dao();  //如果连接对象为空,则重新调用构造方法
    return conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    ResultSet.CONCUR_UPDATABLE).executeQuery(sql);//执行查询
    } catch (SQLException e) {
    e.printStackTrace();
    return null; //返回null值
    } finally {
    }
    }
    private static int executeUpdate(String sql) { //更新方法
    try {
    if(conn==null)  new Dao(); //如果连接对象为空,则重新调用构造方法
    return conn.createStatement().executeUpdate(sql);//执行更新
    } catch (SQLException e) {
    e.printStackTrace();
    return -1;
    } finally {
    }
    }
    public static void close() {//关闭方法
    try {
    conn.close();//关闭连接对象
    } catch (SQLException e) {
    e.printStackTrace();
    }finally{
    conn = null; //设置连接对象为null值
    }
    }
    /*
     * 管理员登录方法
     */
    public static Operater check(String name, String password) {
    Operater operater=new Operater();//操作员信息对象
    String sql = "select *  from tb_operator where name='" + name
    + "' and password='" + password + "'and admin=1";//查询字符串
    ResultSet rs = Dao.executeQuery(sql);//执行查询
    try {
    while (rs.next()) {//如果查询到了记录
    operater.setId(rs.getString("id"));//设置操作员编号
    operater.setName(rs.getString("name"));//设置操作员用户名
    operater.setGrade(rs.getString("admin"));//设置操作员等级
    operater.setPassword(rs.getString("password"));//设置管理员密码
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    Dao.close(); //关闭连接对象
    return operater;//返回操作员信息对象
    }
    }
      

  3.   

    异常信息很明确了,你都关闭了链接,就不能再进行操作了
    就如你说的那样,不要调用close方法
      

  4.   

    全部调用之后再close么,查询操作和关闭connection操作分开比较好,
      

  5.   

    原因很简单。在对数据库操作结束后关闭连接是正确的做法,没什么大问题。至于出现:No operations allowed after connection closed。这样的问题原因只有一个,你这里和数据库的连接Connection是一个Static的,程序共享这一个Connection。所以第一次对数据库操作没问题,当把Connection关闭后,第二次还想操作数据库时Connection肯定不存在了。
      

  6.   


    正解CSDN的这个回复编辑器也太他妈比的烂了
      

  7.   

    try this:if(conn==null)  new Dao();  
    ===>>>>>
    if(conn == null || conn.isClosed()) new Dao();=================================================
    题外话楼主的DAO类写得不怎么合理,其实DAO模式不是提供静态方法,而是使用实例方法dao 中的 Connection conn 是静态的。楼主这样做如果是开发 AWT/Swing 类型的系统可能问题不大,但是如果是写jsp/servlet 这类网站这种多线程系统,一定会出问题。
      

  8.   

    ResultSet rs = Dao.executeQuery(sql);//执行查询
    楼主直接用Dao就不对了哦,你要先new一个Dao的实例,然后再调用实例的executeQuery()方法哦,否则执行完close,就没法创建Dao了
      

  9.   

    我没有发现楼主的代码有什么问题,可能有哪个地方没有看到
    1.在close以后连接是被关闭了,但是它也把connection设置为null了
    2.当调用executeQuery时 发现connection为空它有会新建一个connection
    我这边执行了2次都没有问题   代码如下
    public class Test {
        protected static String dbClassName =
                "com.mysql.jdbc.Driver";//数据库连接驱动类
        protected static String dbUrl = "jdbc:mysql://localhost:3306/ssh";//数据库连接URL
        protected static String dbUser = "root";                //数据库用户名
        protected static String dbPwd = "";            //数据库密码
        private static Connection conn = null;                //数据库连接对象
        private Test() {                                        //默认构造函数
            try {
                if (conn == null) {                            //如果连接对象为空
                    Class.forName(dbClassName);                //加载驱动类
                    conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);//获得连接对象
                }
            } catch (Exception ee) {
                ee.printStackTrace();
            }
        }
        private static ResultSet executeQuery(String sql) {    //查询方法
            try {
                if(conn==null)  new Test();  //如果连接对象为空,则重新调用构造方法
                return conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                        ResultSet.CONCUR_UPDATABLE).executeQuery(sql);//执行查询
            } catch (SQLException e) {
                e.printStackTrace();
                return null;                //返回null值
            } finally {
            }
        }
        private static int executeUpdate(String sql) {        //更新方法
            try {
                if(conn==null)  new Test();    //如果连接对象为空,则重新调用构造方法
                return conn.createStatement().executeUpdate(sql);//执行更新
            } catch (SQLException e) {
                e.printStackTrace();
                return -1;
            } finally {
            }
        }
        public static void close() {//关闭方法
            try {
                conn.close();//关闭连接对象
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                conn = null;    //设置连接对象为null值
            }
        }    public static void main(String[] args){
         run();
         run();
            
        }
        public static void run(){
         ResultSet rs = Test.executeQuery("select * from user");
            try {
             rs.next();
                System.out.println(rs.getString(1));
            } catch (SQLException e) {
                e.printStackTrace();  
            }
            Test.close();
        }}
      

  10.   

      Mysql的数据库连接默认等待时限(wait_timeout)是8个小时,在该时限内如果没有使用该Connection(超过了这个时限),Connection就会被关闭。虽然该Connection已经被关闭,但Connection不为空。第一次调用时没有问题的,如果长时间没有使用该Connection,Connection会被Mysql关闭(但不为null)。此时调用该Connection时就会抛出异常com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed by the driver.
      如果一个程序中使用一个共同的static的Connection时,这种问题就很容易出现。查看Mysql的默认wait_timeout值(以下是我的Mysql中的配置)
    show variables like '%timeout%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | connect_timeout            | 10    |
    | delayed_insert_timeout     | 300   |
    | innodb_lock_wait_timeout   | 50    |
    | innodb_rollback_on_timeout | OFF   |
    | interactive_timeout        | 6000  |
    | net_read_timeout           | 30    |
    | net_write_timeout          | 60    |
    | slave_net_timeout          | 3600  |
    | table_lock_wait_timeout    | 50    |
    | wait_timeout               | 6000  |
    +----------------------------+-------+
    10 rows in set (0.00 sec)wait_timeout的值是6000秒。
    解决方法:
    1.修改Mysql的配置文件,添加一个属性,一旦Connection被自动关闭,便进行自动重连
    2.在程序中进行判断,如hemowolf的方式。
    3.使用更高级的数据库连接的jar,老的都会有这种问题。
    4.不直接使用jdbc,改用Spring中的jdbcTemplate。