Класс базы данных Singleton для пула JDBC с использованием Apache Tomcat JDBC - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь настроить класс одноэлементной базы данных, чтобы разрешить пул соединений с базой данных Oracle XE 18c с использованием JDK8 и Tomcat7.

Я не могу скомпилировать исходный код из-за следующей ошибки:

незарегистрированное исключение 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 ]

0 голосов
/ 07 января 2019

Я думаю, что вы должны либо выбросить SQLException в getInstance(), либо обработать его и использовать ресурс try-with (автоматически закрывает ресурсы) вместо 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;
    }
}

Возможно, создание метода инициализации для соединения с базой данных было бы лучшей идеей, чем инициализация всего в конструкторе, но это основано на мнениях.

0 голосов
/ 07 января 2019

Измените код, как показано ниже, Вы должны поймать исключение.

private static  DatabaseManager SINGLE_INSTANCE = null;
static {
    try {
        SINGLE_INSTANCE = new DatabaseManager();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...