代码之家  ›  专栏  ›  技术社区  ›  M.E.

使用apache tomcat jdbc的jdbc池的singleton数据库类

  •  1
  • M.E.  · 技术社区  · 6 年前

    我正在尝试配置一个singleton数据库类,以允许使用JDK8和Tomcat7针对OracleXE18C数据库进行连接池。

    由于以下错误,无法编译源:

    未报告的异常sqlException;必须捕获或声明为 投掷

    Netbeans error

    类源代码:

    package com.example.webapp.db;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.apache.tomcat.jdbc.pool.DataSource;
    import org.apache.tomcat.jdbc.pool.PoolProperties;
    public class DatabaseManager {
    
        private static final DatabaseManager SINGLE_INSTANCE = new DatabaseManager();
    
        private DatabaseManager() throws SQLException {
            PoolProperties p = new PoolProperties();
            p.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
            p.setDriverClassName("oracle.jdbc.driver.OracleDriver");
            p.setUsername("scott");
            p.setPassword("tiger");
            p.setJmxEnabled(true);
            p.setTestWhileIdle(false);
            p.setTestOnBorrow(true);
            p.setValidationQuery("SELECT 1");
            p.setTestOnReturn(false);
            p.setValidationInterval(30000);
            p.setTimeBetweenEvictionRunsMillis(30000);
            p.setMaxActive(100);
            p.setInitialSize(10);
            p.setMaxWait(10000);
            p.setRemoveAbandonedTimeout(60);
            p.setMinEvictableIdleTimeMillis(30000);
            p.setMinIdle(10);
            p.setLogAbandoned(true);
            p.setRemoveAbandoned(true);
            p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
              "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
            DataSource datasource = new DataSource();
            datasource.setPoolProperties(p); 
    
            Connection con = null;
            try {
              con = datasource.getConnection();
              Statement st = con.createStatement();
              ResultSet rs = st.executeQuery("select * from user");
              int cnt = 1;
              while (rs.next()) {
                  System.out.println((cnt++)+". Host:" +rs.getString("Host")+
                    " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
              }
              rs.close();
              st.close();
            } finally {
              if (con!=null) try {con.close();}catch (Exception ignore) {}
            }
        }
    
        public static DatabaseManager getInstance() {
            return SINGLE_INSTANCE;
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   deHaar    6 年前

    我认为你应该扔或处理 SQLException getInstance() 并使用 尝试使用资源 (自动关闭资源)而不是 finally 块。你应该 制作你的 instance 使用构造函数的常量,该构造函数将 Exception 用于初始化。

    package com.example.webapp.db;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.apache.tomcat.jdbc.pool.DataSource;
    import org.apache.tomcat.jdbc.pool.PoolProperties;
    
    public class DatabaseManager {
    
        // not final anymore and null as default
        private static DatabaseManager instance = null;
    
        private DatabaseManager() {
            PoolProperties p = new PoolProperties();
            p.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
            p.setDriverClassName("oracle.jdbc.driver.OracleDriver");
            p.setUsername("scott");
            p.setPassword("tiger");
            p.setJmxEnabled(true);
            p.setTestWhileIdle(false);
            p.setTestOnBorrow(true);
            p.setValidationQuery("SELECT 1");
            p.setTestOnReturn(false);
            p.setValidationInterval(30000);
            p.setTimeBetweenEvictionRunsMillis(30000);
            p.setMaxActive(100);
            p.setInitialSize(10);
            p.setMaxWait(10000);
            p.setRemoveAbandonedTimeout(60);
            p.setMinEvictableIdleTimeMillis(30000);
            p.setMinIdle(10);
            p.setLogAbandoned(true);
            p.setRemoveAbandoned(true);
            p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
                    + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
            javax.sql.DataSource datasource = new DataSource();
            datasource.setPoolProperties(p);
    
            // use a try-with resource to get rid of the finally block...
            try (Connection con = datasource.getConnection()) {
                Statement st = con.createStatement();
                ResultSet rs = st.executeQuery("select * from user");
                int cnt = 1;
    
                while (rs.next()) {
                    System.out.println((cnt++) + ". Host:" + rs.getString("Host")
                            + " User:" + rs.getString("User")
                            + " Password:" + rs.getString("Password"));
                }
    
                rs.close();
                st.close();
            // ... and handle the exception
            } catch (SQLException e) {
                System.err.println("SQLException while constructing the instance of DatabaseManager");
                e.printStackTrace();
            }
        }
    
        public static DatabaseManager getInstance() {
            // check for null here:
            if (instance == null) {
                instance = new DatabaseManager();
            }
            return instance;
        }
    }
    

    也许,为数据库连接创建初始化方法比初始化构造函数中的所有内容更好,但这是基于观点的。

        2
  •  2
  •   Ramesh Subramanian    6 年前

    如下图所示更改代码,您必须捕获异常。

    private static  DatabaseManager SINGLE_INSTANCE = null;
    static {
        try {
            SINGLE_INSTANCE = new DatabaseManager();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }