【问题标题】:Opening and closing database打开和关闭数据库
【发布时间】:2016-08-10 08:29:06
【问题描述】:

我正在开发一个应用程序,该应用程序在我的服务器上记录我的 MySql 数据库。每次想用数据库,获取现有的连接,如果没有,我第一次想。当我进行插入或选择时,效果很好,但在咨询之后,当它结束时,我永远无法恢复连接,也不会返回咨询。

我的数据库类

public class Database {
/**
 * Gets just one instance of the class
 * Connects on construct
 * @returns connection
 */
private Connection _conn = null;
private long timer;

//singleton code
private static Database DatabaseObject;
private Database() {}
public static Database connect() {
    if (DatabaseObject == null)
        DatabaseObject = new Database();
    return DatabaseObject._connect();
}
public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
}
//end singleton code


/**
 * Connects with the defined parameters on Config
 * Prevents re-connection if object was already connected
 * @throws SQLException
 */
private Database _connect() {
    try {
    if (this._conn == null || !this._conn.isValid(0)) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Properties connProps = new Properties();
            connProps.put("user", Config.Config.DB_USER);
            connProps.put("password", Config.Config.DB_PASS);
            this._conn = DriverManager.
                        getConnection("jdbc:" + Config.Config.DB_DBMS + "://" + Config.Config.DB_HOST + ":"
                                + Config.Config.DB_PORT + "/" + Config.Config.DB_NAME, Config.Config.DB_USER, Config.Config.DB_PASS);
            timer = System.currentTimeMillis();
        } catch (ClassNotFoundException e) {
            System.out.println("Where is your MySQL JDBC Driver?");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("Could not connect to DB");
            e.printStackTrace();
        }
    } else {
        try {
            long tmp = System.currentTimeMillis() - timer;
            if (tmp > 1200000) { //3600000 one hour ; 1200000 twenty minutes
                System.out.println("Forcing reconnection ("+tmp+" milliseconds passed since last connection)");
                this.close();
                this._connect();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Forcing reconnection");
            this._conn = null;
            this._connect();
        }
    }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return this;
}

/**
 * Closes connections
 * This has to be invoked when database connection is no longer needed
 * @throws SQLException
 */
public void close() throws SQLException {
    if (this._conn != null) {
        this._conn.close();
        this._conn = null;
    }
}

   /**
    * Getter for connection
    * @return
    */
   public Connection get() {
      return this._conn;
   }
}

我查询如下函数:

private Statement sment = null;
private PreparedStatement psment = null;
private ResultSet rset = null;
public boolean existsByNameAndUserId(String md5, int userId, int eventId) {
    Connection conn = Database.connect().get();
    try {
        psment = conn.prepareStatement("SELECT * FROM files "
                                        + "WHERE user_id = ? AND md5 = ? AND evento_id = ?");
        psment.setInt(1, userId);
        psment.setString(2, md5);
        psment.setInt(3, eventId);
        rset = psment.executeQuery();

        if (rset.next()) {
            return true;
        }
    } catch (Exception e) {

        e.printStackTrace();
    }

    return false;
}

private void close() {
    try { if (rset != null) rset.close(); } catch (Exception e) {System.out.println(e.getMessage());};
    try { if (psment != null) psment.close(); } catch (Exception e) {System.out.println(e.getMessage());};
    try { if (sment != null) sment.close(); } catch (Exception e) {System.out.println(e.getMessage());};
}

接下来,我调用上面的函数来查找是否有这些特征的记录,如果没有,我做一个插入。

String SQL_INSERT = "INSERT INTO files (evento_id, user_id, path, thumb, preview, width, height, md5, numero_corredor, created, modified) "
        + "VALUES (?,?,?,?,?,?,?,?,?,NOW(),NOW())";
public void save(List<components.File.Schema> files) throws SQLException {
    try (
            Connection conn = Database.connect().get();
            PreparedStatement statement = conn.prepareStatement(SQL_INSERT);
        ) {
            int i = 0;

            for (components.File.Schema file : files) {
                if(!existsByNameAndUserId(file.getMd5(), file.getUserId(), file.getEventId())){
                    statement.setInt(1, file.getEventId());
                    statement.setInt(2, file.getUserId());
                    statement.setString(3, file.getPath());
                    statement.setString(4, file.getPreview());
                    statement.setString(5, file.getThumb());

                    statement.setInt(6, file.getWidth());
                    statement.setInt(7, file.getHeight());
                    statement.setString(8, file.getMd5());
                    statement.setString(9, null);
                    statement.addBatch();
                    i++;
                    if (i % 1000 == 0 || i == files.size()) {
                        statement.executeBatch(); // Execute every 1000 items.
                    }
                }
            }
       }
}

【问题讨论】:

  • 试图提供代码并尽可能解释清楚,但不理解?我将尝试编写并添加更多代码。 @Razib
  • 不,我认为最好的问题是简洁易懂的问题。
  • 我的问题是因为当做一个数据库查询机翼运行良好时,第二次失败。没有返回值,不会陷入异常,不会出错。只是因为连接丢失了数据库,我试图找出问题但找不到原因。每次我使用数据库获取现有连接,如果建立,我认为是一个新的,但这对我不起作用。
  • @Razib 编辑我的帖子,希望能更好地理解它

标签: java mysql database jdbc


【解决方案1】:

您的问题是由于您将 Connection conn = Database.connect().get() 放在 try-with-resources 语句中,这是您应该做的,但它关闭了您的连接,当您再次调用它时,因为方法 _connect() 没有有一个有效的测试,它不会创建一个新的连接。有效的测试是this._conn == null || !this._conn.isValid(0),实际上,在您的原始测试中,您调用this._conn.isValid(0),它将在我们的上下文中返回false,因为连接已关闭,因此它不会创建新的连接,这不是我们想要的。

响应更新: 问题的第二部分是在保存method 你调用existsByNameAndUserId 关闭当前连接,你应该只关闭语句并让方法保存关闭连接。

【讨论】:

  • 尼古拉斯,您好,感谢您的回答。我明白你的意思,我想我想我添加一个方法代码close(),因为在这个方法中我没有关闭数据库,编辑并在我的帖子代码中失败
  • 不需要添加 close 方法,因为 Connection 是 AutoCloseable,所以它已经在 try-with-resources 语句的上下文中被调用
  • 我理解并修改了我的代码以验证您所说的连接,但仍然以相同的方式工作。第一次查询数据库,又不能访问了。
  • 我试过了,但还是一样,编辑我的帖子,让你看到我的代码,看看我有什么错误,你说的是否合乎逻辑并且应该有效,
  • 如果我是你,我会改用数据源,但这不是这里的主题,你只是尝试调试看看会发生什么?
猜你喜欢
  • 1970-01-01
  • 2019-12-31
  • 2017-02-01
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多