Java/JavaFX-在尝试db连接时检查是否存在internet连接

Java/JavaFX-在尝试db连接时检查是否存在internet连接,java,postgresql,javafx,connection,Java,Postgresql,Javafx,Connection,假设我在JavaFX中创建了一个简单的登录窗口,通过连接到postgresql数据库来检查用户名和密码是否匹配,成功后用户登录 现在,只要存在互联网连接,这种方法就可以很好地工作 但是,如果没有internet连接,JVM会反复抛出PSQLException,应用程序会冻结一分钟左右。我以为我在连接课上看到了这些。它是由SocketTimeoutException引起的 有没有人知道我如何处理这个问题,使错误消息显示在GUI中,而不是冻结和异常 我的连接类如下所示: public class D

假设我在JavaFX中创建了一个简单的登录窗口,通过连接到postgresql数据库来检查用户名和密码是否匹配,成功后用户登录

现在,只要存在互联网连接,这种方法就可以很好地工作

但是,如果没有internet连接,JVM会反复抛出PSQLException,应用程序会冻结一分钟左右。我以为我在连接课上看到了这些。它是由SocketTimeoutException引起的

有没有人知道我如何处理这个问题,使错误消息显示在GUI中,而不是冻结和异常

我的连接类如下所示:

public class DBConnection {
/* DB credentials, modify as needed */
private static final String HOST     = "<HOST>";
private static final String DATABASE = "<DATABASE>";
private static final String USERNAME = "<USERNAME>";
private static final String PASSWORD = "<PASSWORD>";
private static final String PORT     = "5432";

/* !!DO NOT EDIT BELOW!! */
private static final String JDBC_DRIVER = "org.postgresql.Driver";
private static final String URL         = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;

private static final ComboPooledDataSource POOL = new ComboPooledDataSource();

private static Connection conn = null;

public static void Connect() throws PropertyVetoException, SQLException{
    try {
        POOL.setDriverClass(JDBC_DRIVER);
    }catch (PropertyVetoException e){
        System.out.println("Could not locate JDBC driver");
        e.printStackTrace();
        throw e;
    }
    //Connection parameters
    POOL.setJdbcUrl(URL);
    POOL.setUser(USERNAME);
    POOL.setPassword(PASSWORD);

    //Pool properties
    POOL.setMinPoolSize(3);
    POOL.setAcquireIncrement(5);
    POOL.setMaxPoolSize(100);
    POOL.setMaxStatements(180);

    try {
        conn = POOL.getConnection();
    } catch (SQLException e) {
        System.out.println("Could not establish connection to database");
        e.printStackTrace();
        throw e;
    }
}
public static ResultSet ExecuteQuery(String query) throws PropertyVetoException, SQLException {
    PreparedStatement st = null;
    ResultSet rs = null;
    CachedRowSet crs = null;
    try {
        Connect();
        System.out.println("Select statement: " + query + "\n");
        st = conn.prepareStatement(query);
        rs = st.executeQuery();
        crs = new CachedRowSetImpl();
        crs.populate(rs);
    }catch (Exception e){
        System.out.println("Problem occurred at executeQuery operation: " + e);
        throw e;
    }finally {
        DbUtils.closeQuietly(conn, st, rs);
    }
    return crs;
}
public static void ExecuteUpdate(String query) throws PropertyVetoException, SQLException {
    PreparedStatement st = null;
    try {
        Connect();
        st = conn.prepareStatement(query);
        st.executeUpdate();
    }catch (Exception e){
        System.out.println("Problem occurred at executeUpdate operation: " + e);
        throw e;
    }finally {
        DbUtils.closeQuietly(st);
        DbUtils.closeQuietly(conn);
    }
}
}
公共类数据库连接{
/*数据库凭据,根据需要进行修改*/
私有静态最终字符串HOST=“”;
私有静态最终字符串数据库=”;
私有静态最终字符串USERNAME=“”;
私有静态最终字符串密码=”;
专用静态最终字符串端口=“5432”;
/*!!请勿编辑以下内容*/
私有静态最终字符串JDBC_DRIVER=“org.postgresql.DRIVER”;
私有静态最终字符串URL=“jdbc:postgresql://”+主机+:“+端口+”/“+数据库;
私有静态最终ComboPooledDataSource池=新ComboPooledDataSource();
专用静态连接conn=null;
public static void Connect()引发PropertyVetoException,SQLException{
试一试{
setDriverClass(JDBC_驱动程序);
}捕获(PropertyVetOe异常){
System.out.println(“找不到JDBC驱动程序”);
e、 printStackTrace();
投掷e;
}
//连接参数
setJdbcUrl(URL);
setUser(用户名);
设置密码(PASSWORD);
//池属性
POOL.setMinPoolSize(3);
池.增量(5);
POOL.setMaxPoolSize(100);
POOL.setMaxStatements(180);
试一试{
conn=POOL.getConnection();
}捕获(SQLE异常){
System.out.println(“无法建立到数据库的连接”);
e、 printStackTrace();
投掷e;
}
}
公共静态结果集ExecuteQuery(字符串查询)抛出PropertyVetoException、SQLException{
PreparedStatement st=null;
结果集rs=null;
CachedRowSet crs=null;
试一试{
Connect();
System.out.println(“选择语句:“+query+”\n”);
st=conn.prepareStatement(查询);
rs=圣执行机构();
crs=新的CachedRowSetImpl();
crs.填充(rs);
}捕获(例外e){
System.out.println(“在执行程序操作时出现问题:”+e);
投掷e;
}最后{
德布提尔斯。安静地关闭(康涅狄格州,圣路易斯);
}
返回crs;
}
公共静态void ExecuteUpdate(字符串查询)引发PropertyVetoException、SQLException{
PreparedStatement st=null;
试一试{
Connect();
st=conn.prepareStatement(查询);
st.executeUpdate();
}捕获(例外e){
System.out.println(“执行更新操作时出现问题:+e”);
投掷e;
}最后{
安静地关闭(st);
DbUtils.安静地关闭(康涅狄格州);
}
}
}
像往常一样,在其中添加另一层抽象来解决您的问题

意思是:你可以有一个班,负责理解“我们有联系吗?”。它可以通过周期性地ping数据库服务器来获得这些知识(有关如何做到这一点的想法,请参阅)。所以,在你要求建立一个连接之前,你需要征求“AreWeConnectedService”的意见

该服务基本上是这样工作的:

public class DBConnection {
/* DB credentials, modify as needed */
private static final String HOST     = "<HOST>";
private static final String DATABASE = "<DATABASE>";
private static final String USERNAME = "<USERNAME>";
private static final String PASSWORD = "<PASSWORD>";
private static final String PORT     = "5432";

/* !!DO NOT EDIT BELOW!! */
private static final String JDBC_DRIVER = "org.postgresql.Driver";
private static final String URL         = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;

private static final ComboPooledDataSource POOL = new ComboPooledDataSource();

private static Connection conn = null;

public static void Connect() throws PropertyVetoException, SQLException{
    try {
        POOL.setDriverClass(JDBC_DRIVER);
    }catch (PropertyVetoException e){
        System.out.println("Could not locate JDBC driver");
        e.printStackTrace();
        throw e;
    }
    //Connection parameters
    POOL.setJdbcUrl(URL);
    POOL.setUser(USERNAME);
    POOL.setPassword(PASSWORD);

    //Pool properties
    POOL.setMinPoolSize(3);
    POOL.setAcquireIncrement(5);
    POOL.setMaxPoolSize(100);
    POOL.setMaxStatements(180);

    try {
        conn = POOL.getConnection();
    } catch (SQLException e) {
        System.out.println("Could not establish connection to database");
        e.printStackTrace();
        throw e;
    }
}
public static ResultSet ExecuteQuery(String query) throws PropertyVetoException, SQLException {
    PreparedStatement st = null;
    ResultSet rs = null;
    CachedRowSet crs = null;
    try {
        Connect();
        System.out.println("Select statement: " + query + "\n");
        st = conn.prepareStatement(query);
        rs = st.executeQuery();
        crs = new CachedRowSetImpl();
        crs.populate(rs);
    }catch (Exception e){
        System.out.println("Problem occurred at executeQuery operation: " + e);
        throw e;
    }finally {
        DbUtils.closeQuietly(conn, st, rs);
    }
    return crs;
}
public static void ExecuteUpdate(String query) throws PropertyVetoException, SQLException {
    PreparedStatement st = null;
    try {
        Connect();
        st = conn.prepareStatement(query);
        st.executeUpdate();
    }catch (Exception e){
        System.out.println("Problem occurred at executeUpdate operation: " + e);
        throw e;
    }finally {
        DbUtils.closeQuietly(st);
        DbUtils.closeQuietly(conn);
    }
}
}
  • 它有一个内部字段“已连接”
  • 它有一个内部线程,该线程周期性地ping另一侧
  • 如果ping失败,您将转到
    connected=false
    (您可能还记得时间戳)
  • 如果ping在某个点再次工作,则重新切换字段
然后该服务有一个查询该标志的方法

但当然,在服务告诉您“一切正常”后,您仍然可能会立即失去连接。因此,您必须进一步退一步并修复问题的“其他部分”:您必须使用另一个线程,然后使用SwingUX线程来执行该
getConnection()
调用。理想情况下,您甚至可以使用两个线程:一个线程进行实际调用;另一个是强制执行超时


除此之外:确保您阅读并理解Oracle必须告诉您的内容!还有另一个链接——你可能也想看看这个模式。

哦,是的,这肯定会奏效。我会看看是否可以实现这个,然后返回结果。谢谢你!是的,我读过一些关于JavaFX中并发性的文章。这基本上归结为应用程序线程不是线程安全的,因此JavaFX提供了自己的API来处理并发性,如果我不是完全错的话。现在我要弄清楚如何正确地利用它。让我们这样说:任何UI框架都需要处理多线程。因此,每个框架都有自己的规则如何处理线程。你只需要理解事情是如何运作的。好吧,一般来说,我对线程不是很有经验。我是否可以让“AreWeConnectedService”根据结果返回一个布尔值,然后在检查布尔值的同时尝试连接,如果我们能够连接,最终会中断连接?编辑:不,经过重新考虑,如果我没有完全错的话,我在尝试连接到数据库时仍然会遇到同样的问题,因为while条件已经存在,但在我们检查连接后但在数据库连接之前,实际的互联网连接可能会中断。我只是忘记按下按钮,我感谢你提供的帮助,非常感谢。然而,我忍不住想知道你是否只是在这里发表这样的评论,谢谢你及时接受!