代码之家  ›  专栏  ›  技术社区  ›  Sergio

方法com/mysql/jdbc/PreparedStatement。isClosed()Z是抽象的

  •  -1
  • Sergio  · 技术社区  · 6 年前

    我正在尝试更改我的应用程序的连接池,以便使用Tomcat的连接池(org.apache.Tomcat.jdbc.pool)而不是“apache Commons DBCP”。

    但是,我在尝试连接到DB时遇到以下错误:

    javax.servlet.ServletException: java.lang.AbstractMethodError: Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:909)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:838)
    ...
    ...
    

    我在其他链接中读到,通常这是MySQL JDBC驱动程序版本的问题,然而,我刚刚更新到最新的Connector/J版本(MySQL-Connector-java-8.0.11.jar),但仍然会遇到这个错误。

    以下是如何创建连接池:

    首先,这取决于上下文。我的应用程序META-INF目录中的xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <Context>
    <Resource
        name="rhwebDB"
        auth="Container"
        type="javax.sql.DataSource"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        testWhileIdle="true"
        testOnBorrow="true"
        testOnReturn="false"
        validationQuery="SELECT 1"
        validationInterval="30000"
        timeBetweenEvictionRunsMillis="30000"
        maxActive="10"
        minIdle="5"
        maxIdle="10"
        maxWait="10000"
        initialSize="2"
        removeAbandonedTimeout="60"
        removeAbandoned="true"
        logAbandoned="true"
        minEvictableIdleTimeMillis="30000"              
        username="dbUser"
        password="dbPwd"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/rhweb2015"/>
    </Context>
    

    然后我有一个DBUtil。所有其他库使用的类:

    public class DBUtil {
    
        static Connection connection = null;
        static {
            try {
                Context context = new InitialContext();
                DataSource ds = (DataSource)context.lookup("java:comp/env/rhwebDB");
                connection = ds.getConnection();
            } catch (NamingException e) {
                System.out.println("DBUtil.NamingException" + e);
            } catch (SQLException e) {
                System.out.println("DBUtil.SQLException" + e);
            }
        }
    
        public static Connection getConnection() {
            return connection;
        }
    
        public static synchronized void closeConnection(Connection conn) {
            try {
                if (conn != null && !conn.isClosed())
                    conn.close();
            } catch (SQLException sqle) {
                System.out.println("Error closing the connection ! " + sqle);
            }
    
        }
    }
    

    最后,所有其他java库都像这样使用连接池:

    public boolean someFunction( String myValue ){
        Connection conn = null;
        boolean fRetVal = false;
    
        String query = "select something from anytable";
    
        try {
            conn = DBUtil.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery( query );
    
            if ( rs.next() )
                fRetVal = true;
    
            rs.close();
            stmt.close();
    
        } catch( SQLException ex ) {
                System.out.println(ex);
        }finally{
            DBUtil.closeConnection(conn);
        }
    
        return fRetVal;
    }
    

    我错过什么了吗?Tomcat启动时,我没有收到任何错误。

    JDK版本:8(java版本“1.8.0\u 111”) Tomcat版本:8.5.8 MySQL服务器5.6

    任何帮助都将不胜感激

    1 回复  |  直到 6 年前
        1
  •  3
  •   user207421    6 年前

    这是完全错误的。你养着一条狗,自己在叫。不能使用静态 Connections 第一,第二,使用静态 Connection 违背了使用连接池的全部目的。应该是这样的:

    public class DBUtil {
    
        static DataSource ds;
        static {
            try {
                Context context = new InitialContext();
                ds = (DataSource)context.lookup("java:comp/env/rhwebDB");
            } catch (NamingException e) {
                System.out.println("DBUtil.NamingException" + e);
            } catch (SQLException e) {
                System.out.println("DBUtil.SQLException" + e);
            }
        }
    
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
    }
    

    并且,使用“试用资源”关闭所有内容:

    public boolean someFunction( String myValue ){
        boolean fRetVal = false;
    
        String query = "select something from anytable";
    
        try (Connection conn = DBUtil.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery( query )) {
            if ( rs.next() )
                fRetVal = true;
        } catch( SQLException ex ) {
            System.out.println(ex);
        }
    
        return fRetVal;
    }
    

    &OE公司

    但请注意,您并不真正需要 DBUtil 一点都不难。您可以注入 DataSource 任何需要的地方,都可以通过注释来实现。