Java / javaFX:每个查询与db的新连接?

时间:2017-04-08 00:35:46

标签: java database postgresql javafx database-connection

所以,我在javaFX中创建一个应用程序(仅用于学习目的),它主要由每个选项卡的子fxmls的tabpane组成。每个选项卡都包含一个tableview,其中包含从数据库收集的数据。为了连接到数据库,我有一个单独的连接类,它使用c3p0创建一个新的连接池。

我的第一个问题是:我是否应该为每次对数据库进行的查询创建(并关闭)新连接?

示例:输入新选项卡后,我创建一个新连接,收集数据,然后关闭连接(使用语句和结果集)。

如果没有,我将如何以适当和有效的方式做到这一点?

我的第二个问题:目前我的应用程序正在执行上述操作,但我注意到如果我将应用程序打开一段时间而不与之交互,每当我再次开始与它进行交互时,它就会冻结在它继续之前。当时查看的当前表格显示"表格中没有数据",直到我切换到另一个选项卡,然后数据再次正确显示。为什么会这样?

我对Java一般都很陌生,而且通过搜索类似于我的问题我找不到任何东西。我的数据库是postgres db。

编辑1: 关于问题2: 我已经遵循了mvc-pattern,不确定这是不是一个好主意,但这是另一个问题。

有四个类在表的创建中起作用,它们是:

控制器类:

public class StockController {

//tableview from fxml-file
@FXML
private TableView<List<Object>> stockTable;

//
private BuildDataModel stockData = new BuildDataModel();

//Called from main whenever currently active tab changes to this tab.
public void CreateView(){
    String query = "SELECT component.name, stock.* FROM component NATURAL JOIN stock";

    stockData.BuildData(stockTable, query);

}
//Called from main whenever currently active tab changes to another tab.
public void DestroyView(){
    if(!stockTable.getColumns().isEmpty()) {
        stockData.DeleteData();
    }
}
}

模特课:

public class BuildDataModel {

private Connection conn;
@FXML
private TableView<List<Object>> tableview;

public TableData data;

private TableData getAllData(String query){
    List<List<Object>> data = new ArrayList<>();
    List<String> columnNames = new ArrayList<>();
    PreparedStatement st = null;
    ResultSet rs = null;

    try {
        conn = PostgresConnection.CreateConnection();
        st = conn.prepareStatement(query);
        rs = st.executeQuery();

        //We create columns
        int columnCount = rs.getMetaData().getColumnCount();
        for(int i = 1; i <= columnCount; i++) {
            String columnName = rs.getMetaData().getColumnName(i);
            columnNames.add(columnName);
        }
        //We populate our tabledata object with the data
        while(rs.next()){
            List<Object> row = new ArrayList<>();
            for(int i = 1; i <= columnCount; i++){
                row.add(rs.getObject(i));

            }
            data.add(row);
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }
    finally {
        DbUtils.closeQuietly(conn, st, rs);

    }
    return new TableData(columnNames, data);
}
//Called from controller class, calls getAllData with the specified query
//and populates tableview based on this.
public void BuildData(TableView<List<Object>> tableview, String query) {
    this.tableview = tableview;
    try {
        data = getAllData(query);
        for (int i = 0 ; i < data.getNumColumns(); i++) {
            TableColumn<List<Object>, Object> column = new TableColumn<>(data.getColumnName(i));
            int columnIndex = i;
            column.setCellValueFactory(cellData ->
                    new SimpleObjectProperty<>(cellData.getValue().get(columnIndex)));
            tableview.getColumns().add(column);
        }

        tableview.getItems().setAll(data.getData());
    }
    catch (Exception e) {
    }

}

public void DeleteData(){
    tableview.getColumns().clear();
}}

连接类:

public class PostgresConnection {

//DB credentials, modify as needed
private static final String HOST     = "localhost";
private static final String DATABASE = "<INSERT DATABASE HERE>";
private static final String USERNAME = "<INSERT USERNAME HERE>";
private static final String PASSWORD = "<INSERT PASSWORD HERE>";

//Default postgresql port, don't change unless you know what you're doing.
private static final String PORT     = "5432";
private static final String URL      = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;
private static final String DRIVER_NAME = "org.postgresql.Driver";

private static Connection conn;

//Disables C3P0-pool logging
static {
    Properties p = new Properties(System.getProperties());
    p.put("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
    p.put("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "OFF");
    System.setProperties(p);
}

private static ComboPooledDataSource cpds = new ComboPooledDataSource();

public static Connection CreateConnection() throws SQLException {
    try {
        cpds.setDriverClass(DRIVER_NAME);
    } catch (PropertyVetoException e) {
        e.printStackTrace();
    }
    cpds.setJdbcUrl(URL);
    cpds.setUser(USERNAME);
    cpds.setPassword(PASSWORD);
    cpds.setMinPoolSize(3);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(100);
    cpds.setMaxStatements(180);
    return cpds.getConnection();
}}

和DAO:

public class TableData {

private final List<String> columnNames;
private final List<List<Object>> data;

public TableData(List<String> columnNames, List<List<Object>> data) {
    this.columnNames = columnNames;
    this.data = data;
}

public int getNumColumns() {
    return columnNames.size();
}

public String getColumnName(int index) {
    return columnNames.get(index);
}

public int getNumRows() {
    return data.size();
}

public Object getData(int column, int row) {
    return data.get(row).get(column);
}

public List<List<Object>> getData() {
    return data;
}
public void removeData(){
    data.clear();
    columnNames.clear();
}}

0 个答案:

没有答案